vue中使用微信JS-SDK 报错 invalid signature 签名无效 问题分析记录

问题描述

微信JS-SDK说明文档

之前在 html+js 的项目中使用微信JS-SDKwx.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 都不行。
真是让人头疼啊。。。。抓狂。。。。

等问题解决了再来更新问题的原因和解决办法,哎............

以上是2019-07-25下午



以下是2019-07-26上午

解决了

来更新了,问题解决了,去掉了encodeURIComponent就好了。。。。

那么为什么官方文档中的常见错误及解决方法第6条,以及别的文章里都说要encodeURIComponent呢?

6.确保你获取用来签名的url是动态获取的,动态页面可参见实例代码中php的实现方式。如果是html的静态页面在前端通过ajax将url传到后台签名,前端需要用js获取当前页面除去'#'hash部分的链接(可用location.href.split('#')[0]获取,而且需要encodeURIComponent),因为页面一旦分享,微信客户端会在你的链接末尾加入其它参数,如果不是动态获取当前链接,将导致分享后的页面签名失败。
有同学疑惑这个encodeURIComponent是干嘛用的,其实具体很简单,就是因为我们在微信分享的时候,会自动给我们带上参数(记得告诉后端的伙伴要decodeURIComponent),切记只要带参数就一定要转码!

然而,在vue里,我们把encodeURIComponent去掉了,反倒问题解决了,额。。。。。

参考资料

微信JS-SDK说明文档 附录5-常见错误及解决方法
vue 单页面(SPA) history模式调用微信jssdk 跳转后偶尔 "invalid signature"错误解决方案
关于微信JSSDK中遇到的“invalid signature”的天坑
微信 jssdk 签名错误 invalid signature
VUE解决微信签名,SPA微信invalid signature问题,完美处理
微信jssdk常见错误及解决方法
vue cli单页模式下偶尔报错 invalid signature 的错误
vue 项目如何引入微信sdk,使用微信分享接口
微信分享JSSDK-invalid signature签名错误的解决方案
微信JS-SDK获取signature签名以及config配置

vue-router HTML5 History 模式

相关推荐