history模式微信自定义分享
前言
最近做的Vue SPA项目涉及到微信自定义分享,最初只是在指定页面下实现微信的二次分享功能。但是因为移动端使用的是vue-router的history模式,所以在iOS端微信和Android端微信分享出来的截然不同,大多数是iOS端微信会分享失败。上网查询了一些文档说是iOS端微信不支持pushState的H5新特性。还有就是iOS端微信记录的URL是首次访问网页时的网址,所以在使用window.location.href获取当前网址来换取微信的签名校验信息时候就会导致签名校验失败,致使最终微信分享失败。
解决方案
iOS端微信处理方法:保存首次进入页面时候的路径,在需要调用微信分享的页面内利用首次进入页面时候的路径URL来换取iOS端微信分享的签名。
Android端微信处理方法:Android端微信每次切换路由时候都会刷新页面,故在需要使用微信分享的页面直接获取当前页面所在路径的URL即使用window.location.href来换取微信分享的签名即可。
判断iOS、Android设备方法
Android设备环境:
let ua = navigator.userAgent;
// 方法一
let isAndroid = ua.indexOf("Android") > -1 || ua.indexOf("Linux") > -1;
// 方法二
let isAndroid = ua.indexOf('Android') > -1 || ua.indexOf('Adr') > -1;
// 方法三
let isAndroid = /(Android)/i.test(navigator.userAgent);
iOS设备环境:
// 方法一
let isiOS = !!window.__wxjs_is_wkwebview;
// 方法二
let isiOS = /iPhone|mac|iPod|iPad/i.test(navigator.userAgent);
// 方法三
let u = navigator.userAgent;
let isiOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/);
主要代码
- 封装wxShare.js
import axios from "axios";
import store from "../store";
/* 微信自定义分享 */
/**
* url:获取微信分享签名的url地址
* device:iOS&Android设备的区分
* isShare:当前所在路径是否需要分享
* */
const WeChatShare = (url, device, isShare) => {
if (!isShare) {
return;
}
let xxx = store.state.xxx;
let shareLink = window.location.origin + "?xxx=" + xxx;
if (store.state.xxxx == "") {
return;
}
let { title, imgUrl, link, desc } = store.state.xxxx;
if (device == "iOS") {
// 获取iOS微信首次存储的URL
url = sessionStorage.getItem("iOS-URL");
} else {
url = window.location.href;
}
if (url.includes("#")) {
url = url.split("#")[0];
}
// 获取时间戳
axios
.get("wx/api", { params: { url: decodeURIComponent(url) } })
.then(res => {
if (res.data.code == 1) {
let { timestamp, noncestr, signature } = res.data.result_data;
// 校验
wx.config({
debug: false,
appId: "appId",
timestamp: timestamp,
nonceStr: noncestr,
signature: signature,
jsApiList: ["checkJsApi", "updateAppMessageShareData", "updateTimelineShareData"]
});
// 检测
wx.ready(() => {
wx.checkJsApi({
jsApiList: ["updateAppMessageShareData", "updateTimelineShareData"],
success: function (res) { }
});
// 自定义“分享给朋友”及“分享到QQ”(1.4.0)
wx.updateAppMessageShareData({
title: title,
desc: desc,
link: link,
imgUrl: imgUrl,
success: () => { }
});
// 自定义“分享到朋友圈”及“分享到QQ空间”(1.4.0)
wx.updateTimelineShareData({
title: title,
link: link,
imgUrl: imgUrl,
success: () => { }
});
});
}
})
.catch(err => {
console.log("JSSDK share error:", err);
});
};
- 分享链接处理
/* 处理分享链接 */
const shareLink = location => {
let origin = location.origin,
search = location.search;
if (search.includes("&")) {
search = search.split("&")[0];
}
let link = origin + search;
return link;
};
- router.js多路径自定义分享设置
// 设备判断
let ua = navigator.userAgent;
// Android
let isAndroid = ua.indexOf("Android") > -1 || ua.indexOf("Linux") > -1;
// iOS
let isIos = !!window.__wxjs_is_wkwebview;
// 微信二次分享
router.afterEach((to, from) => {
let authUrl = `${window.location.origin}${to.fullPath}`;
let allowShare = !!to.meta.allowShare;
// IOS
if (isIos) {
authUrl = sessionStorage.getItem("iOS-URL");
WeChatShare(authUrl, "iOS", allowShare);
}
// Android
if (isAndroid) {
setTimeout(() => {
WeChatShare(authUrl, "android", true);
}, 400);
}
});
注:
在vue项目中只是分享某一个路径下的页面,即可在当前页面路径下引入写好的微信分享文件方法,在需要分享的页面进行调用即可。
在Vue SPA项目 history模式中,指定页面需要实现动态分享,其余路径页面实现固定分享,既可以在router.js的 router.afterEach((to,from)=>{}) 全局生命周期钩子函数中调用微信分享方法即可实现指定路径页面动态分享,其余路径页面固定分享的需求。
hash模式,直接按照Android端微信的调用方式即可。如有问题,可依据此思路作为参考,并结合实际需求进行相应的调整。