问题原因

参考链接:http://www.ahaiba.cn/index.php/xinwenzhongxin/2019/10-31/181.html
今天,iOS签名小编主要带大家了解一个比较常见,也困扰了很多朋友的问题:IOS微信上Vue单页面应用JSSDK签名失败后如何进行解决的问题,对需要的朋友是比较有价值的,有兴趣的朋友可以斟酌参考一下:
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来处理。

解决方案

https://www.jianshu.com/p/1bab11e3a3d7?from=groupmessage
https://blog.csdn.net/sjn0503/article/details/75634858
https://blog.csdn.net/sjn0503/article/details/74745608
http://www.512pic.com/184/6583-0.html
我们可以在路由跳转的时候保存一下进入首页的URL,然后在录音页面判断如果是IOS系统,那么就使用我们当时记录的URL,如果不是那么就正常获取当前页面的URL就可以了,下面上代码

  • 路由守卫 ```javascript // router // 路由开始进入 router.beforeEach((to, from, next) => { // 进入页面时保存首次进入的地址 if (window.entryUrl === undefined) { window.entryUrl = location.href.split(‘#’)[0] } })
  1. - 工具库
  2. ```javascript
  3. // 判断浏览器环境
  4. const userAgent = global.navigator.userAgent
  5. export const inAndroid = /Android/i.test(userAgent)
  6. export const inIOS = /iPhone|iPad|iPod/i.test(userAgent)
  7. export const inMicroMessenger = /MicroMessenger/i.test(userAgent)
  8. export const inWindowsWechat = /WindowsWechat/i.test(userAgent)
  • 页面
    1. //分享
    2. onShareConfig() {
    3. // console.log('是否是ios', inIOS)
    4. // console.log('配置分享')
    5. let url = ''
    6. if (inIOS) {
    7. console.log(window.entryUrl)
    8. url = window.entryUrl
    9. } else {
    10. url = window.location.href
    11. }
    12. ...
    13. 请求服务器获取jssdk配置
    14. }