问题描述
微信 JS-SDK 说明文档
之前在 html+js
的项目中使用 微信 JS-SDK
,wx.config
配置正常,使用图片上传和扫一扫等功能都正常。
现在的问题是,在 vue history 模式 项目中,一直是签名无效,iOS 和 Android 都不行。
按照官方文档中的 1~6 排查了都没问题,打印出来的 url 编码前后和后端获取到的签名的 url 编码前后都是一致的,但就是一直 invalid signature 签名无效。
常见错误及解决方法
invalid signature 签名错误。建议按如下顺序检查:
1. 确认签名算法正确,可用 http://mp.weixin.qq.com/debug… 页面工具进行校验。
2. 确认 config 中 nonceStr(js 中驼峰标准大写 S), timestamp 与用以签名中的对应 noncestr, timestamp 一致。
3. 确认 url 是页面完整的 url(请在当前页面 alert(location.href.split(‘#’)[0])确认),包括 ’http(s)://’ 部分,以及 ’?’ 后面的 GET 参数部 > 分, 但不包括 ’#’hash 后面的部分。
4. 确认 config 中的 appid 与用来获取 jsapi_ticket 的 appid 一致。
5. 确保一定缓存 access_token 和 jsapi_ticket。
6. 确保你获取用来签名的 url 是动态获取的,动态页面可参见实例代码中 php 的实现方式。如果是 html 的静态页面在前端通过 ajax 将 url 传到后台签 > 名,前端需要用 js 获取当前页面除去 ’#’hash 部分的链接(可用 location.href.split(‘#’)[0]获取, 而且需要 encodeURIComponent),因为页 > 面一旦分享,微信客户端会在你的链接末尾加入其它参数,如果不是动态获取当前链接,将导致分享后的页面签名失败。
问题分析
经过查资料发现,参考资料前两篇里都说是
从 A 页面,跳转到 B 页面,由于没有刷新,B 调用 JSSDK 的 内容,由于 vue-router 切换的时候 都是操作的浏览器历史记录,真实 url 为第一次刚进入时的 url。每次路由变化时都重新请求下签名,签名的 url 需要用第一次进入时的 url
IOS:微信 IOS 版,每次切换路由,SPA 的 url 是不会变的,发起签名请求的 url 参数必须是当前页面的 url 就是最初进入页面时的 url
Android:微信安卓版,每次切换路由,SPA 的 url 是会变的,发起签名请求的 url 参数必须是当前页面的 url(不是最初进入页面时的)
在另一篇文章微信 jssdk 签名错误 invalid signature 里,说是:
在 iOS 下,签名依然失败!因为在 iOS 下,微信需要你传递的是入口 URL,而不是当前页面的 URL!
比如说,你在微信公众号的某个菜单链接进入了 A 页面,然后从 A 页面的某个链接跳转到 B 页面,然后你在 B 页面获取签名,如果是在安卓下,你应 > 该用 B 页面的 URL 地址来获取,但是在 iOS 下,你还必须用 A 页面的 URL 地址来获取,否则就还是签名失败!
有点儿懵 -_-||
尝试解决
按前两篇文里说的方法试着改了一下代码
在 A 组件增加:
if (navigator.userAgent.indexOf('iPhone') !== -1) {
// IOS 记录微信菜单打开时的 url
window.entryUrl = location.href.split('#')[0]
}
在 B 组件修改:
let href = window.location.href.split('#')[0]
let signLink = /(Android)/i.test(navigator.userAgent) ? href : window.entryUrl
let encodeURI = encodeURIComponent(signLink)
let data = {url: encodeURI}
let url = '/.../getconfig.json' // 接口省略了
this.$get(url, data, response => {
let rtn = response.data
wx.config({// beta: true, // 必须这么写,否则 wx.invoke 调用形式的 jsapi 会有问题 [这是企业微信的使用]
// debug: false, // 关闭调试模式
debug: true, // 开启调试模式, 调用的所有 api 的返回值会在客户端 alert 出来
appId: rtn.appId, // 必填,公众号的唯一标识
timestamp: rtn.timestamp, // 必填,生成签名的时间戳
nonceStr: rtn.nonceStr, // 必填,生成签名的随机串
signature: rtn.signature, // 必填,签名,见附录 1
jsApiList: ['checkJsApi', 'chooseImage', 'uploadImage'] // 必填,需要使用的 JS 接口列表,所有 JS 接口列表见附录 2
})
结果:
还是 invalid signature 签名无效,依然是 iOS 和 Android 都不行。
真是让人头疼啊。。。。抓狂。。。。
等问题解决了再来更新问题的原因和解决办法,哎 …………
参考资料
vue 单页面 (SPA) history 模式调用微信 jssdk 跳转后偶尔 “invalid signature” 错误解决方案
关于微信 JSSDK 中遇到的“invalid signature”的天坑
微信 jssdk 签名错误 invalid signature
vue-router HTML5 History 模式