这两天在做微信自定义分享的需求,使用JS-SDK的页面注入配置信息时安卓系统config:ok,ios系统config:invalid signature签名错误。然后去查微信jssdk的文档,里面所说的config:invalid signature可能原因你都一个个查验过发现没有问题,但是还是提示签名错误,是不是很抓狂很蛋疼???然后你再去查请求配置信息时的动态URL是否有问题,你会发现安卓ios打印出来的url都是正确的,问题究竟出在哪里呢???就问你难不难受!!!
安卓系统签名没问题,ios系统签名有问题,那么肯定就是url的问题了。其实问题就出在ios系统对vue-router的history的支持上,由于Vue的spa特点,尽管你打印出来都是你所要的当前页面url,只要你不刷新页面,ios获取到的url永远是你进入这个项目的第一个url,这样的话你请求签名就会变成动态url不一致导致签名失败。不信???你可以到签名失败的那个页面手动刷新一次,然后你会发现此时签名就成功了,因为刷新后获取的第一个url就是你当前的页面url。既然如此我们就需要在如何获取真正的动态url这里做文章,至于那些设置js安全域名、获取timestamp,nonceStr,signature这些我就不说了,百度一下大把解决方案。
解决方法就是在路由守卫afterEach中判断是ios系统时添加一个获取当前url的函数,此函数只需要在url上添加一个随机数参数然后用location.replace更新即可,具体代码如下:
1.在util.js文件中定义函数:
import { getSignature } from '@/api/api'
// 判断手机系统
export function isAndroid () { var u = navigator.userAgent var isAndroid = u.indexOf('Android') > -1 || u.indexOf('Linux') > -1 if (isAndroid) { return true } else { return false } }
// ios系统进行重定向获取最新的url便于微信获取权限签名 export function iosUrlRefresh (to) { let iosRandom = 'iosRandom=' + new Date().getTime() // 新增随机参数 let url = location.protocol + '//' + location.host + '/mobileTest' + to.fullPath // 重组url 注意项目路径 if (url.indexOf('?') > 0) { url = url + '&' + iosRandom } else { url = url + '?' + iosRandom } window.location.replace(url) }
// 清除url中手动新增的随机数iosRandom export function getCurrentUrl () { let url = location.href.replace(/&iosRandom=[0-9]{13}/g, '') window.history.replaceState({}, document.title, url) }
// 自定义分享 export function shareWxApi (title, desc, link, imgUrl) { getSignature(encodeURIComponent(location.href.split('#')[0])).then(data => { wx.config({ debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。 appId: data.result.appId, // 必填,公众号的唯一标识 timestamp: data.result.timestamp, // 必填,生成签名的时间戳 nonceStr: data.result.noncestr, // 必填,生成签名的随机串 signature: data.result.signature, // 必填,签名,见附录1 jsApiList: ['onMenuShareTimeline', 'onMenuShareAppMessage', 'onMenuShareQQ', 'onMenuShareWeibo', 'onMenuShareQZone'] // 必填,需要使用的JS接口列表,所有JS接口列 表见附录2 }) wx.ready(function () { wx.onMenuShareAppMessage({ // 分享给朋友 title: title, // 分享标题 desc: desc, // 分享描述 link: link, // 分享链接 imgUrl: imgUrl, // 分享图标 success: function () { // 用户确认分享后执行的回调函数 }, cancel: function () { // 用户取消分享后执行的回调函数 } }) wx.onMenuShareTimeline({ // 朋友圈分享 title: title, // 分享标题 link: link, // 分享链接 imgUrl: imgUrl, // 分享图标 success: function () { // 用户确认分享后执行的回调函数 }, cancel: function () { // 用户取消分享后执行的回调函数 } }) wx.onMenuShareQQ({ title: title, // 分享标题 desc: desc, // 分享描述 link: link, // 分享链接 imgUrl: imgUrl, // 分享图标 success: function () { // 用户确认分享后执行的回调函数 }, cancel: function () { // 用户取消分享后执行的回调函数 } }) wx.onMenuShareWeibo({ title: title, // 分享标题 desc: desc, // 分享描述 link: link, // 分享链接 imgUrl: imgUrl, // 分享图标 success: function () { // 用户确认分享后执行的回调函数 }, cancel: function () { // 用户取消分享后执行的回调函数 } }) wx.onMenuShareQZone({ title: title, // 分享标题 desc: desc, // 分享描述 link: link, // 分享链接 imgUrl: imgUrl, // 分享图标 success: function () { // 用户确认分享后执行的回调函数 }, cancel: function () { // 用户取消分享后执行的回调函数 } }) }) wx.error(function (e) { console.warn(e) }) }, f => { }) }
2.在路由守卫写入函数:
import { isAndroid, isoUrlRefresh } from '@/utils/util'
router.beforeEach((to, from, next) => { next() }
router.afterEach((to, from) => { // 若为ios系统则进行重定向获取最新的url便于微信获取权限签名 if (!isAndroid()) { !to.query.iosRandom && iosUrlRefresh(to) } })
3.在需要使用微信自定义分享的页面中写入函数:
import { setCurrentUrl, shareWxApi } from '@/utils/util'
mounted () { setCurrentUrl() shareWxApi('解决微信自定义分享问题', 'Vue微信自定义分享时安卓系统config:ok,ios系统config:invalid signature签名错误的解决办法','https://www.cnblogs.com/zishang91/p/10755488.html', 'https://xxx.png') }