详解IOS微信上Vue单页面应用JSSDK签名失败解决方案
作者:我叫她兜兜 发布时间:2024-04-30 10:25:40
背景
手机型号:
型号: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"
// 获取真实有效微信签名URL
function 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
来源:https://segmentfault.com/a/1190000017009560


猜你喜欢
- Vue 的用法没有变化:<template lang="pug"> transition(name=&quo
- TensorFlow训练时,遇到内存不断增长,最终导致内存不足,进程被杀死。在这里我不准备对造成这一现象的所有原因进行探讨,只是记录一下我在
- 前言在前几篇博客中,分别就棋子的颜色识别、模板匹配等定位方式进行了介绍和实践,这一篇博客就来验证一下github中最热门的跳一跳 * 中采用的
- 在师兄的推荐下入坑vue.js ,发现不知如何运行GitHub上的开源项目,很尴尬。通过查阅网上教程,成功搭建好项目环境,同时对前段工程化有
- 前言在不远的将来,实现一定程度上的语音支持将成为日常科技的基本要求,整合了语音识别的python程序提供了其他技术无法比拟的交互性和可访问性
- 阿里云 视频直播 配置 及 PHP-SDK 接入教程个人感觉,阿里的文档比微信的要坑很多…微信最多是有些比较重要的东西放到比较不起眼、比较难
- 具体代码如下所示:#字符串反转def reverse (s): rt = '' for i in r
- 本文为大家分享了解决Mysql存储引擎MyISAM常见问题的方法,供大家参考,具体内容如下一、处理MyISAM存储引擎的表损坏在使用MySQ
- 使用Python解析各种格式的数据都很方便,比如json、txt、xml、csv等。用于处理简单的数据完全足够用了,而且代码简单易懂。前段时
- 层次化索引是pandas的一项重要功能,它使你能在一个轴上拥有多个(两个以上)索引级别。创建一个Series,并用一个由列表或数组组成的列表
- 简介卷积神经网络(Convolutional Neural Network, CNN)是深度学习技术中极具代表的网络结构之一,在图像处理领域
- 当使用pytorch写网络结构的时候,本人发现在卷积层与第一个全连接层的全连接层的input_features不知道该写多少?一开始本人的做
- 总的来说视觉设计是一个很大的范畴,囊括了我们身边很多产品的再创作设计,比如工业产品设计,广告设计,新媒体设计,服饰设计,还有我们这里要讨论的
- 在用Python绘制红楼梦词云图文章中讲到我们使用Python把红楼梦中的核心词汇给绘画出来了,但是,红楼梦这么唯美的书,给我们乌漆麻黑的搞
- 1、查看当前所有连接的详细资料:./mysqladmin -uadmin -p -h10.140.1.1 processlist2、只查看当
- DataFrame是一个组织成命名列的数据集。它在概念上等同于关系数据库中的表或R/Python中的数据框架,但其经过了优化。DataFra
- 以上述图片举例,要求 相对 的顺时针夹角。注意:这里使用图像坐标系1 定义求顺时针角度的函数 import numpy as npdef
- while循环是在Python中的循环结构之一。 while循环继续,直到表达式变为假。表达的是一个逻辑表达式,必须返回一个true或fal
- 本文实例为大家分享了python实现多人聊天室的具体代码,供大家参考,具体内容如下一、目的以实现小项目的方式,来巩固之前学过的Python基
- 也不一定,以前从来没有深入的研究过sql查询,最近买了一本T-SQL查询的书,把以前忽视的问题都记录一下 以前一直模模糊糊的把sqlserv