微信 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 相关文章推荐
jQuery EasyUI API 中文文档 - ComboGrid 组合表格
Oct 13 Javascript
5秒后跳转到另一个页面的js代码
Oct 12 Javascript
弹出最简单的模式化遮罩层的js代码
Dec 04 Javascript
用box固定长宽实现图片自动轮播js代码
Jun 09 Javascript
javascript实现在某个元素上阻止鼠标右键事件的方法和实例
Aug 12 Javascript
Javascript中的Prototype到底是什么
Feb 16 Javascript
jQuery基于BootStrap样式实现无限极地区联动
Aug 26 Javascript
JavaScript编写九九乘法表(两种任选)
Feb 04 Javascript
判断颜色是否合法的正则表达式(详解)
May 03 Javascript
vuejs手把手教你写一个完整的购物车实例代码
Jul 06 Javascript
bootstrap datetimepicker控件位置异常的解决方法
Nov 23 Javascript
微信小程序实现录制、试听、上传音频功能(带波形图)
Feb 27 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
PHP 中的面向对象编程:通向大型 PHP 工程的办法
2006/12/03 PHP
让PHP支持页面回退的两种方法
2008/01/10 PHP
php页面跳转代码 输入网址跳转到你定义的页面
2013/03/28 PHP
Ubuntu 16.04中Laravel5.4升级到5.6的步骤
2018/12/07 PHP
function, new function, new Function之间的区别
2007/03/08 Javascript
基于dom编程中 动态创建与删除元素的使用
2013/04/17 Javascript
JS过滤url参数特殊字符的实现方法
2013/12/24 Javascript
JavaScript sup方法入门实例(把字符串显示为上标)
2014/10/20 Javascript
使用Chrome调试JavaScript的断点设置和调试技巧
2014/12/16 Javascript
使用mini-define实现前端代码的模块化管理
2014/12/25 Javascript
JavaScript获取网页中第一个图片id的方法
2015/04/03 Javascript
javascript实现根据时间段显示问候语的方法
2015/06/18 Javascript
jQuery实现按钮只点击一次后就取消点击事件绑定的方法
2015/06/26 Javascript
js实现网站最上边可关闭的浮动广告条代码
2015/09/04 Javascript
JQuery中解决重复动画的方法
2016/10/17 Javascript
JavaScript登录验证码的实现
2016/10/27 Javascript
Vue.js结合bootstrap实现分页控件
2017/03/10 Javascript
javascript实现多张图片左右无缝滚动效果
2017/03/22 Javascript
微信小程序实现点击按钮移动view标签的位置功能示例【附demo源码下载】
2017/12/06 Javascript
angularjs性能优化的方法
2018/09/05 Javascript
Vue中使用clipboard实现复制功能
2018/09/05 Javascript
基于Vue实现电商SKU组合算法问题
2019/05/29 Javascript
[48:53]2014 DOTA2华西杯精英邀请赛 5 25 LGD VS VG第一场
2014/05/26 DOTA
[02:11]2014DOTA2 TI专访VG战队Fenrir:队伍气氛良好
2014/07/11 DOTA
[02:42]决战东方!DOTA2亚洲邀请赛重启荣耀之争
2017/03/17 DOTA
python通过scapy获取局域网所有主机mac地址示例
2014/05/04 Python
100行python代码实现跳一跳辅助程序
2018/01/15 Python
使用Python进行AES加密和解密的示例代码
2018/02/02 Python
Flask框架实现给视图函数增加装饰器操作示例
2018/07/16 Python
安装Anaconda3及使用Jupyter的方法
2020/10/27 Python
德国箱包网上商店:koffer24.de
2016/07/27 全球购物
英国领先的葡萄酒专家:Majestic Wine
2017/05/30 全球购物
中学教师培训制度
2014/01/31 职场文书
2014年班组建设工作总结
2014/12/01 职场文书
2015年街道除四害工作总结
2015/05/15 职场文书
十大公认最好看的动漫:《咒术回战》在榜,《钢之炼金术师》第一
2022/03/18 日漫