微信 jssdk 签名错误invalid signature的解决方法


Posted in Javascript onJanuary 14, 2019

几乎每一个开发用于微信公众号页面的工程师都遇到过微信jssdk报的各种错误,通常是permission denied,类似这样:

微信 jssdk 签名错误invalid signature的解决方法

通常他们会建议你把debug选项开开,比如这样:

wechat.config({
   debug: true,
   appId: appId,
   timestamp: timestamp,
   nonceStr: nonceStr,
   signature: signature,
   jsApiList: ['scanQRCode'],
  });

结果你又遇到了invalid signature。类似这样:

微信 jssdk 签名错误invalid signature的解决方法

签名不对,这是什么意思?可是这签名是后端给过来的,我怎么知道它为什么不对?后端用的是标准算法,不可能不对啊。

查网上各种教程,或者微信官网,他们总是不厌其烦地告诉你,让你去检查签名算法,然而根本没有用!

90%的这种情况下,其实只是一个原因:你用于计算签名的URL地址不对,跟算法没有任何关系,完全不必浪费时间去看什么签名算法。

微信要求:如果我们需要在页面中调用微信的某个方法,则必须用这个页面的URL地址获取签名。听上去似乎很好理解,但是实际上URL地址包含的部分很多,有问号,有#号,你所要做的是取出#前面的部分。比如说你的URL地址是这样:https://www.abc.com/abc.html?abc=def#xyz,那么你用于计算签名的URL地址不可以是https://www.abc.com/abc.html,也不能是https://www.abc.com/abc.html?abc=def#xyz,而必须只能是https://www.abc.com/abc.html?abc=def

如何获取当前页面的URL地址呢?这个很简单:

let wechaturl = window.location.href.split('#')[0];

然而你以为事情就这样结束了?太天真。你的页面还是无法正常使用微信函数的。

因为:微信内嵌浏览器在iOS和安卓下的表现不一样。

在安卓下,你确实用上面的方法是可以调用了。但是在iOS下,签名依然失败!因为在iOS下,微信需要你传递的是入口URL,而不是当前页面的URL

比如说,你在微信公众号的某个菜单链接进入了A页面,然后从A页面的某个链接跳转到B页面,然后你在B页面获取签名,如果是在安卓下,你应该用B页面的URL地址来获取,但是在iOS下,你还必须用A页面的URL地址来获取,否则就还是签名失败!

知道了原因,就有很多种解决办法。

首先,我们可以在入口的A页面里增加这样的判断:

if (navigator.userAgent.indexOf('iPhone') !== -1) {
  window.wechaturl = window.location + '';
}

然后,在B页面需要调用签名的地方,再增加这样的判断:

let wechaturl = window.location.href.split('#')[0];
if (window.wechaturl !== undefined) {
 wechaturl = window.wechaturl;
}

这样我们就有效地区分开了iOS和安卓。但问题是在iOS下,如果我的另外一个菜单入口是B页面,我从B页面跳转到A页面,这时候我的入口链接被强制变成了A页面,依然会产生签名失败的错误。

所以我们还需要在微信公众号的每一个入口菜单链接里加一个特殊的参数,例如wechat=1,变成这样:https://www.abc.com/abc.html?abc=def&wechat=1

然后我们再增加一层判断,变成这样:

if (navigator.userAgent.indexOf('iPhone') !== -1) {
 if (this.$route.query.wechat !== undefined && this.$route.query.wechat === '1') {
  window.wechaturl = window.location + '';
 }
}

这里我用了vue的写法,但原理是一样的。只有我检测到了wechat这个参数,我才认为当前页面是入口页面,如果没有检测到,则不必强行设置为入口页面。

这样似乎就解决了微信签名失败的问题。

但是,我们又遇到了另外一种情况:在微信小程序里用web-view内嵌的网页,在安卓下也报permission deniedinvalid signature错误。不过有了上面的经验,我们诊断错误根源还是URL入口地址的问题。果然,在安卓下用入口地址获取签名成功,而用当前地址获取签名失败,为此,我们在入口页面里再加一个判断:

if (navigator.userAgent.indexOf('miniProgram') !== -1) {
 window.wechaturl = window.location + '';
}

至此,各种签名错误的问题才算是全部解决。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
JavaScript窗口功能指南之在窗口中书写内容
Jul 21 Javascript
URL编码转换,escape() encodeURI() encodeURIComponent()
Dec 27 Javascript
IE8 浏览器Cookie的处理
Jan 31 Javascript
JavaScript中神奇的call()方法
Mar 12 Javascript
原生JS实现LOADING效果
Mar 16 Javascript
JS中跨页面调用变量和函数的方法(例如a.js 和 b.js中互相调用)
Nov 01 Javascript
详解JavaScript模块化开发
Dec 04 Javascript
JS删除数组里的某个元素方法
Feb 03 Javascript
layui实现table加载的示例代码
Aug 14 Javascript
Vue resource三种请求格式和万能测试地址
Sep 26 Javascript
Vue如何使用混合Mixins和插件开发详解
Feb 05 Javascript
VueCli4项目配置反向代理proxy的方法步骤
May 17 Javascript
详解从react转职到vue开发的项目准备
Jan 14 #Javascript
node全局变量__dirname与__filename的区别
Jan 14 #Javascript
微信小程序时间轴实现方法示例
Jan 14 #Javascript
浅谈webpack devtool里的7种SourceMap模式
Jan 14 #Javascript
关于vue的npm run dev和npm run build的区别介绍
Jan 14 #Javascript
用npm-run实现自动化任务的方法示例
Jan 14 #Javascript
详解vue-cli 2.0配置文件(小结)
Jan 14 #Javascript
You might like
PHP4与PHP3中一个不兼容问题的解决方法
2006/10/09 PHP
探讨:web上存漏洞及原理分析、防范方法
2013/06/29 PHP
JavaScript 事件的一些重要说明
2009/10/25 Javascript
jQuery中append、insertBefore、after与insertAfter的简单用法与注意事项
2020/04/04 Javascript
jquery取消选择select下拉框示例代码
2014/02/22 Javascript
浅谈javascript的分号的使用
2015/05/12 Javascript
JavaScript常用判断写法大全(推荐)
2016/05/30 Javascript
又一枚精彩的弹幕效果jQuery实现
2016/07/25 Javascript
javascript的函数劫持浅析
2016/09/26 Javascript
js控制一个按钮是否可点击(可使用)disabled的实例
2017/02/14 Javascript
JS中使用 after 伪类清除浮动实例
2017/03/01 Javascript
Vue + Webpack + Vue-loader学习教程之功能介绍篇
2017/03/14 Javascript
Angular2 http jsonp的实例详解
2017/08/31 Javascript
Koa2 之文件上传下载的示例代码
2018/03/29 Javascript
深入理解es6块级作用域的使用
2019/03/28 Javascript
JavaScript This指向问题详解
2019/11/25 Javascript
浅谈vue权限管理实现及流程
2020/04/23 Javascript
Vue2.x和Vue3.x的双向绑定原理详解
2020/11/05 Javascript
Vue在H5 项目中使用融云进行实时个人单聊通讯
2020/12/14 Vue.js
JS实现纸牌发牌动画
2021/01/19 Javascript
[01:00:25]2018DOTA2亚洲邀请赛3月30日 小组赛A组 VG VS Liquid
2018/03/31 DOTA
[01:35:13]DOTA2-DPC中国联赛 正赛 DLG vs PHOENIX BO3 第一场 1月18日
2021/03/11 DOTA
python中set常用操作汇总
2016/06/30 Python
python dict.get()和dict['key']的区别详解
2016/06/30 Python
Python sqlite3事务处理方法实例分析
2017/06/19 Python
Python实现运行其他程序的四种方式实例分析
2017/08/17 Python
Python字符串逆序输出的实例讲解
2019/02/16 Python
python找出一个列表中相同元素的多个索引实例
2019/06/11 Python
Python的log日志功能及设置方法
2019/07/11 Python
python如何爬取网页中的文字
2020/07/28 Python
HTML5 Web 存储详解
2016/09/16 HTML / CSS
瑞典Happy Socks美国官网:购买色彩斑斓的快乐袜子
2016/10/19 全球购物
乌克兰机票、铁路和巴士票、酒店搜索、保险:Tickets.ua
2020/01/11 全球购物
出纳岗位职责范本
2015/03/31 职场文书
2016大学迎新晚会开场白
2015/11/24 职场文书
一文搞懂如何实现Go 超时控制
2021/03/30 Python