微信 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 相关文章推荐
超级24小时弹窗代码 24小时退出弹窗代码 100%弹窗代码(IE only)
Jun 11 Javascript
基于jquery的兼容各种浏览器的iframe自适应高度的脚本
Aug 13 Javascript
运算符&&的三个不同层次
Apr 07 Javascript
js兼容火狐获取图片宽和高的方法
May 21 Javascript
javascript实现标签切换代码示例
May 22 Javascript
jquery输入数字随机抽奖特效的简单实现代码
Jun 10 Javascript
jquery.serialize() 函数语法及简单实例
Jul 08 Javascript
JavaScript实现的微信二维码图片生成器的示例
Oct 26 Javascript
Bootstrap CSS组件之按钮下拉菜单
Dec 17 Javascript
JS中精巧的自动柯里化实现方法
Dec 12 Javascript
element 结合vue 在表单验证时有值却提示错误的解决办法
Jan 22 Javascript
VUE+node(express)实现前后端分离
Oct 13 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获取错误信息的方法
2015/07/17 PHP
PHP实现根据数组某个键值大小进行排序的方法
2018/03/13 PHP
php 使用html5 XHR2实现上传文件与进度显示功能示例
2020/03/03 PHP
nginx 设置多个站跨域
2021/03/09 Servers
比较全的JS checkbox全选、取消全选、删除功能代码
2008/12/19 Javascript
javascript实现tabs选项卡切换效果(扩展版)
2013/03/19 Javascript
JavaScript运行机制之事件循环(Event Loop)详解
2014/10/10 Javascript
jQuery插件pagination实现分页特效
2015/04/12 Javascript
javascript html5实现表单验证
2016/03/01 Javascript
BootStrap iCheck插件全选与获取value值的解决方法
2016/08/24 Javascript
详解js运算符单竖杠“|”与“||”的用法和作用介绍
2016/11/04 Javascript
微信小程序 图片绝对定位(背景图片)
2017/04/05 Javascript
JS实现线性表的顺序表示方法示例【经典数据结构】
2017/04/11 Javascript
移动端网页开发调试神器Eruda的介绍与使用技巧
2017/10/30 Javascript
了解ESlint和其相关操作小结
2018/05/21 Javascript
Vue.js中对css的操作(修改)具体方式详解
2018/10/30 Javascript
Python实现简单登录验证
2016/04/13 Python
Python学习小技巧之列表项的推导式与过滤操作
2017/05/20 Python
Python 多核并行计算的示例代码
2017/11/07 Python
Python 字符串操作(string替换、删除、截取、复制、连接、比较、查找、包含、大小写转换、分割等)
2018/03/19 Python
Python用for循环实现九九乘法表
2018/05/31 Python
IronPython连接MySQL的方法步骤
2019/12/27 Python
tensorflow实现测试时读取任意指定的check point的网络参数
2020/01/21 Python
Python小白垃圾回收机制入门
2020/06/09 Python
西班牙品牌鞋子、服装和配饰在线商店:Esdemarca
2021/02/17 全球购物
学习十八届三中全会精神实施方案
2014/02/17 职场文书
投标授权委托书范文
2014/08/02 职场文书
高一学年自我鉴定范文(3篇)
2014/09/26 职场文书
党员批评与自我批评发言材料
2014/10/14 职场文书
晋江市人民政府党组群众路线教育实践活动整改方案
2014/10/25 职场文书
2015年社会实践个人总结
2015/03/06 职场文书
人生遥控器观后感
2015/06/11 职场文书
实习报告范文
2019/07/30 职场文书
Nginx服务器添加Systemd自定义服务过程解析
2021/03/31 Servers
Redis+Lua脚本实现计数器接口防刷功能(升级版)
2022/02/12 Redis
鲲鹏 CentOS 7 安装Python3.7
2022/05/11 Servers