微信 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 技巧大全(新手入门篇)
May 12 Javascript
基于JQUERY的多级联动代码
Jan 24 Javascript
js获取时间(本周、本季度、本月..)
Nov 22 Javascript
SeaJS入门教程系列之SeaJS介绍(一)
Mar 03 Javascript
一个网页标题title的闪动提示效果实现思路
Mar 22 Javascript
jQuery中:focus选择器用法实例
Dec 30 Javascript
JS实现随机乱撞彩色圆球特效的方法
May 05 Javascript
AngularJS基础 ng-click 指令示例代码
Aug 01 Javascript
Vue中render函数的使用方法
Jan 31 Javascript
通过jquery.cookie.js实现记住用户名、密码登录功能
Jun 20 jQuery
JS实现网站吸顶条
Jan 08 Javascript
vue项目使用$router.go(-1)返回时刷新原来的界面操作
Jul 26 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 json_decode函数详细解析
2014/02/17 PHP
php文件上传 你真的掌握了吗
2016/11/28 PHP
Laravel框架使用monolog_mysql实现将系统日志信息保存到mysql数据库的方法
2018/08/16 PHP
两个SUBMIT按钮,如何区分处理
2006/08/22 Javascript
JQuery 绑定事件时传递参数的实现方法
2009/10/13 Javascript
javascript自执行函数之伪命名空间封装法
2010/12/25 Javascript
一款Jquery 分页插件的改造方法(服务器端分页)
2011/07/11 Javascript
javascript打印html内容功能的方法示例
2013/11/28 Javascript
javascript向后台传送相同属性的参数即数组参数
2014/02/17 Javascript
JavaScript二维数组实现的省市联动菜单
2014/05/08 Javascript
jQuery焦点控制图层展示延迟隐藏的方法
2015/03/09 Javascript
深入理解JavaScript中的箭头函数
2015/07/28 Javascript
微信小程序  生命周期详解
2016/10/27 Javascript
ES6字符串模板,剩余参数,默认参数功能与用法示例
2017/04/06 Javascript
防止页面url缓存中ajax中post请求的处理方法
2017/10/10 Javascript
详解Vue2.0配置mint-ui踩过的那些坑
2018/04/23 Javascript
vue 的点击事件获取当前点击的元素方法
2018/09/15 Javascript
微信小程序自定义tabBar组件开发详解
2020/09/24 Javascript
webpack中如何使用雪碧图的示例代码
2018/11/11 Javascript
vue2.x 通过后端接口代理,获取qq音乐api的数据示例
2019/10/30 Javascript
uni-app使用微信小程序云函数的步骤示例
2020/05/22 Javascript
[06:15]2016国际邀请赛中国区预选赛单车采访:我顶WINGS
2016/06/27 DOTA
利用Python2下载单张图片与爬取网页图片实例代码
2017/12/25 Python
tensorflow创建变量以及根据名称查找变量
2018/03/10 Python
关于Python作用域自学总结
2019/06/10 Python
Pycharm使用之设置代码字体大小和颜色主题的教程
2019/07/12 Python
解决在keras中使用model.save()函数保存模型失败的问题
2020/05/21 Python
python 绘制国旗的示例
2020/09/27 Python
HTML5调用手机发短信和打电话功能
2020/04/29 HTML / CSS
Antonioli美国在线商店:时尚前卫奢华
2019/07/29 全球购物
护士实习鉴定范文
2013/12/22 职场文书
詹天佑教学反思
2014/04/30 职场文书
为什么代码规范要求SQL语句不要过多的join
2021/06/23 MySQL
iSCSI服务器CHAP双向认证配置
2022/04/01 Servers
JavaScript正则表达式实现注册信息校验功能
2022/05/30 Java/Android
vscode内网访问服务器的方法
2022/06/28 Servers