时间:2021-05-25
背景
手机型号:
型号:iphone 7 / iphone xs max
版本:ios 10.3.1 / ios 12.1
微信版本:WeChat 6.7.3
问题还原:
Vue应用(vue-router)上使用history模式,在某个页面内调用微信JSSDK相关API,如扫码、分享等,使用当前页面URL总会出现签名错误(invalid signature),导致API调用失败。
问题根源
Vue-Router进行路由切换的时候,总是会操作浏览器的历史记录,从而响应页面URL变化。
在JSSDK文档页面有这么一句话:
同一个url仅需调用一次,对于变化url的SPA的web app可在每次url变化时进行调用,目前Android微信客户端不支持pushState的H5新特性,所以使用pushState来实现web app的页面会导致签名失败,此问题会在Android6.2中修复
但根据多次测试情况来看,情况恰好相反,在Android下直接使用 window.location.href 得出的URL进行签名是完全没问题(可能已升级至Android6.2以上版本),在IOS上就不行了。
这是因为在IOS上,无论路由切换到哪个页面,实际真正有效的的签名URL是【第一次进入应用时的URL】。
比如进入应用首页是: https://m.app.com,需要使用JSSDK的页面A是:https://m.app.com/product1/123,无论从首页进入到A页面之前,中间跳转过多少次路由,最终签名有效的URL还是首页URL。
解决方案
方案一
直接粗暴处理方式:
在进入需要使用JSSDK页面(B)的前一个页面(A),即 A > B,直接使用 window.location.href 或 window.open 打开B页面,此时因为B页面是直接刷新方式进入,所以当前B页面URL无论IOS或Android都是可以直接拿来签名的。
这种方式处理缺点也很明显,如页面刷新抖动太厉害不够平滑过渡,再比如B页面需要从vuex中取出缓存信息,如果这些缓存信息不是通过vuex保存在localstorage的话,取出来的肯定都是空的。
方案二
思路:既然IOS仅可使用第一次进入应用的URL来签名,那么在vuex上缓存一个微信签名URL,IOS保存第一次进入应用的URL,Android则缓存为每个页面的URL。签名时,直接从缓存拿出签名URL来处理。
// 全局判断是否IOS方法function isIos(){ const u = navigator.userAgent; return u.indexOf("iPhone") > -1 || u.indexOf("Mac OS") > -1;}1. 定义vuex缓存
...{ state: { wechatSignUrl: "" }, mutations: { setWechatSignUrl(state, wxSignUrl) { // 关键点 // IOS仅记录第一次进入页面时的URL // IOS微信切换路由实际URL不变,只能使用第一进入页面的URL进行签名 if (isIos() && state.wxSignUrl !== '') { return; } state.wxSignUrl = wxSignUrl; } }, getters: { getWechatSignUrl: (state) => state.wxSignUrl }}...关键点在于设置更新微信签名URL判断的地方:首次进入应用页面的时候肯定会触发更新,若是IOS且签名URL已经设置过了,那么就不需要更新设置了,只要不退出或刷新应用,缓存永远都会是首次进入页面URL。
2. 路由守卫内触发更新签名URL
import store form "@/stores"// 获取真实有效微信签名URLfunction getWechatSignUrl(to){ if(isIos()) { return window.location.href; } else { // 此处$appHost需要自行处理 return $appHost + to.fullPath }}...$router.beforeEach((to, from, next) => { store.commit("setWechatSignUrl", getWechatSignUrl(to)); })...在路由守卫内更新签名URL,保证IOS是使用当前页面URL,Android是使用目标路由完整地址再加上域名
3. 使用签名URL调用JSSDK API
在使用JSSDK API的页面通过vuex取出缓存的微信签名URL,然后进行签名。
比如:
import store form "@/stores"...{ methods: { initWechatShareConfig() { const that = this; const wxSignUrl = store.getters['getWechatSignUrl']; const wxShareConfigs = { // 微信分享配置 } // 初始化微信分享 $wechat.share(wxSignUrl, wxShareConfigs); } }}...$wechat.share 是根据JSSDK文档二次封装的分享方法,内部是根据wxSignUrl先进行签名,然后再调用分享API
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
问题描述: Vue单页面用按F5强刷,数据就恢复初始了,这怎么破?解决方案:store.subscribe((mutation,state)=>{sessio
本文介绍了关于vue-resource报错450的解决方案,分享给大家,具体如下:一、基本使用:1.页面引入importvueResourcefrom'vue-
环境vue项目,页面有搜索、筛选项等。需求页面跳转,切换或者刷新,希望可以记住用户在页面的筛选状态方案v1vue有提供一种缓存组件的解决方案—keep-aliv
最近做公众号网页开发,使用微信jssdk页面签名时IOS中一直报错,这才刚开始就被这只拦路虎拦住了,报错如下:然而Android和开发者工具中好得很,没有任何问
关于Vue中路由使用history模式,开发微信H5页面分享时在安卓上签名有效成功,但是在IOS设备上一直报错签名失效问题问题描述:在Vue开发过程中,路由使用