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

问题描述

微信JS-SDK说明文档php

以前在 html+js 的项目中使用微信JS-SDKwx.config 配置正常,使用图片上传和扫一扫等功能都正常。html

如今的问题是,在 vue history模式 项目中,一直是签名无效,iOS和Android 都不行。
按照官方文档中的1~6排查了都没问题,打印出来的url编码先后和后端获取到的签名的url编码先后都是一致的,但就是一直 invalid signature 签名无效。前端

常见错误及解决方法vue

invalid signature签名错误。建议按以下顺序检查:

1.确认签名算法正确,可用http://mp.weixin.qq.com/debug... 页面工具进行校验。ajax

2.确认config中nonceStr(js中驼峰标准大写S), timestamp与用以签名中的对应noncestr, timestamp一致。算法

3.确认url是页面完整的url(请在当前页面alert(location.href.split('#')[0])确认),包括'http(s)://'部分,以及'?'后面的GET参数部> 分,但不包括'#'hash后面的部分。vue-router

4.确认 config 中的 appid 与用来获取 jsapi_ticket 的 appid 一致。json

5.确保必定缓存access_token和jsapi_ticket。segmentfault

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 模式

相关文章
相关标签/搜索