history 模式微信自定义分享

预计阅读时间: 3 分钟

前言

  最近做的Vue SPA项目涉及到微信自定义分享,最初只是在指定页面下实现微信的二次分享功能。但是因为移动端使用的是vue-routerhistory 模式,所以在 iOS 端微信和 Android 端微信分享出来的截然不同,大多数是iOS 端微信会分享失败。上网查询了一些文档说是 iOS 端微信不支持 pushState 的 H5 新特性。还有就是 iOS 端微信记录的 URL 是首次访问网页时的网址,所以在使用window.location.href获取当前网址来换取微信的签名校验信息时候就会导致签名校验失败,致使最终微信分享失败。

解决方案

  iOS 端微信处理方法:保存首次进入页面时候的路径,在需要调用微信分享的页面内利用首次进入页面时候的路径 URL来换取iOS端微信分享的签名。

  Android 端微信处理方法:Android 端微信每次切换路由时候都会刷新页面,故在需要使用微信分享的页面直接获取当前页面所在路径的 URL即使用window.location.href来换取微信分享的签名即可。

判断设备

Android 设备环境:

设备环境
1let ua = navigator.userAgent;
2// 方法一
3let isAndroid = ua.indexOf("Android") > -1 || ua.indexOf("Linux") > -1;
4// 方法二
5let isAndroid = ua.indexOf("Android") > -1 || ua.indexOf("Adr") > -1;
6// 方法三
7let isAndroid = /(Android)/i.test(navigator.userAgent);

iOS 设备环境:

设备环境
1// 方法一
2let isiOS = !!window.__wxjs_is_wkwebview;
3// 方法二
4let isiOS = /iPhone|mac|iPod|iPad/i.test(navigator.userAgent);
5// 方法三
6let u = navigator.userAgent;
7let isiOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/);

主要代码

  • 封装 wxShare.js
代码示例
1import axios from "axios";
2import store from "../store";
3/* 微信自定义分享 */
4/**
5 * url:获取微信分享签名的url地址
6 * device:iOS&Android设备的区分
7 * isShare:当前所在路径是否需要分享
8 *  */
9const WeChatShare = (url, device, isShare) => {
10	if (!isShare) {
11		return;
12	}
13	let xxx = store.state.xxx;
14	let shareLink = window.location.origin + "?xxx=" + xxx;
15	if (store.state.xxxx == "") {
16		return;
17	}
18	let { title, imgUrl, link, desc } = store.state.xxxx;
19	if (device == "iOS") {
20		// 获取iOS微信首次存储的URL
21		url = sessionStorage.getItem("iOS-URL");
22	} else {
23		url = window.location.href;
24	}
25	if (url.includes("#")) {
26		url = url.split("#")[0];
27	}
28	// 获取时间戳
29	axios
30		.get("wx/api", { params: { url: decodeURIComponent(url) } })
31		.then(res => {
32			if (res.data.code == 1) {
33				let { timestamp, noncestr, signature } = res.data.result_data;
34				// 校验
35				wx.config({
36					debug: false,
37					appId: "appId",
38					timestamp: timestamp,
39					nonceStr: noncestr,
40					signature: signature,
41					jsApiList: ["checkJsApi", "updateAppMessageShareData", "updateTimelineShareData"]
42				});
43				// 检测
44				wx.ready(() => {
45					wx.checkJsApi({
46						jsApiList: ["updateAppMessageShareData", "updateTimelineShareData"],
47						success: function (res) {}
48					});
49					// 自定义“分享给朋友”及“分享到QQ”(1.4.0)
50					wx.updateAppMessageShareData({
51						title: title,
52						desc: desc,
53						link: link,
54						imgUrl: imgUrl,
55						success: () => {}
56					});
57					// 自定义“分享到朋友圈”及“分享到QQ空间”(1.4.0)
58					wx.updateTimelineShareData({
59						title: title,
60						link: link,
61						imgUrl: imgUrl,
62						success: () => {}
63					});
64				});
65			}
66		})
67		.catch(err => {
68			console.log("JSSDK share error:", err);
69		});
70};
  • 分享链接处理
代码示例
1/* 处理分享链接 */
2const shareLink = location => {
3	let origin = location.origin,
4		search = location.search;
5	if (search.includes("&")) {
6		search = search.split("&")[0];
7	}
8	let link = origin + search;
9	return link;
10};
  • router.js 多路径自定义分享设置
代码示例
1// 设备判断
2let ua = navigator.userAgent;
3// Android
4let isAndroid = ua.indexOf("Android") > -1 || ua.indexOf("Linux") > -1;
5// iOS
6let isIos = !!window.__wxjs_is_wkwebview;
7// 微信二次分享
8router.afterEach((to, from) => {
9	let authUrl = `${window.location.origin}${to.fullPath}`;
10	let allowShare = !!to.meta.allowShare;
11	// IOS
12	if (isIos) {
13		authUrl = sessionStorage.getItem("iOS-URL");
14		WeChatShare(authUrl, "iOS", allowShare);
15	}
16	// Android
17	if (isAndroid) {
18		setTimeout(() => {
19			WeChatShare(authUrl, "android", true);
20		}, 400);
21	}
22});
总结

  在 vue 项目中只是分享某一个路径下的页面,即可在当前页面路径下引入写好的微信分享文件方法,在需要分享的页面进行调用即可。

  在Vue SPA 项目 history 模式 中,指定页面需要实现动态分享,其余路径页面实现固定分享,既可以在 router.js 的 router.afterEach((to,from)=>{}) 全局生命周期钩子函数中调用微信分享方法即可实现指定路径页面动态分享,其余路径页面固定分享的需求。

hash 模式,直接按照 Android 端微信的调用方式即可。如有问题,可依据此思路作为参考,并结合实际需求进行相应的调整。