微信 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必备 api中英文对照的chm手册 下载
May 03 Javascript
jQuery阻止冒泡和HTML默认操作
Nov 17 Javascript
牛叉的Jquery——Jquery与DOM对象的互相转换及DOM的三种操作
Oct 29 Javascript
4种JavaScript实现简单tab选项卡切换的方法
Jan 06 Javascript
使用struts2+Ajax+jquery验证用户名是否已被注册
Mar 22 Javascript
jQuery实现可展开折叠的导航效果示例
Sep 12 Javascript
微信小程序 video详解及简单实例
Jan 16 Javascript
微信小程序 开发经验整理
Feb 15 Javascript
自定义PC微信扫码登录样式写法
Dec 12 Javascript
vue使用better-scroll实现下拉刷新、上拉加载
Nov 23 Javascript
vue Treeselect下拉树只能选择第N级元素实现代码
Aug 31 Javascript
如何手写一个简易的 Vuex
Oct 10 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中判断一个字符串包含另一个字符串的方法
2007/03/19 PHP
php后台多用户权限组思路与实现程序代码分享
2012/02/13 PHP
PHP抽象类 介绍
2012/06/13 PHP
探讨php中header的用法详解
2013/06/07 PHP
windows7下php开发环境搭建图文教程
2015/01/06 PHP
WordPress中Gravatar头像缓存到本地及相关优化的技巧
2015/12/19 PHP
PHP函数nl2br()与自定义函数nl2p()换行用法分析
2016/04/02 PHP
php连接MSsql server的五种方法总结
2018/03/04 PHP
laravel 解决多库下的DB::transaction()事务失效问题
2019/10/21 PHP
php和js实现根据子网掩码和ip计算子网功能示例
2019/11/09 PHP
使用 JScript 创建 .exe 或 .dll 文件的方法
2011/07/13 Javascript
JavaScript italics方法入门实例(把字符串显示为斜体)
2014/10/17 Javascript
js实现时间显示几天前、几小时前或者几分钟前的方法集锦
2015/05/29 Javascript
jQuery实现的经典竖向伸缩菜单效果代码
2015/09/24 Javascript
javascript中错误使用var造成undefined
2016/03/31 Javascript
JavaScript关于提高网站性能的几点建议(一)
2016/07/24 Javascript
bootstrap与Jquery UI 按钮样式冲突的解决办法
2016/09/23 Javascript
Javascript使用SWFUpload进行多文件上传
2016/11/16 Javascript
BootStrap学习系列之布局组件(下拉,按钮组[toolbar],上拉)
2017/01/03 Javascript
jQuery Ajax实现Select多级关联动态绑定数据的实例代码
2018/10/26 jQuery
vue-axios同时请求多个接口 等所有接口全部加载完成再处理操作
2020/11/09 Javascript
vue+vant实现购物车全选和反选功能
2020/11/17 Vue.js
Python求两个文本文件以行为单位的交集、并集与差集的方法
2015/06/17 Python
keras和tensorflow使用fit_generator 批次训练操作
2020/07/03 Python
Jupyter Notebook添加代码自动补全功能的实现
2021/01/07 Python
英国奢侈品网站:MatchesFashion
2016/12/16 全球购物
马来西亚网上美容店:Hermo.my
2017/11/25 全球购物
美国最受欢迎的度假目的地优惠套餐:BookVIP
2018/09/27 全球购物
简历上的自我评价
2014/02/03 职场文书
毕业自我鉴定总结
2014/03/24 职场文书
设计大赛策划方案
2014/06/13 职场文书
2014年人事部工作总结
2014/12/03 职场文书
教师个人培训总结
2015/02/11 职场文书
物业接待员岗位职责
2015/04/15 职场文书
2015年党风廉政建设目标责任书
2015/05/08 职场文书
分享CSS盒子模型隐藏的几种方式
2022/02/28 HTML / CSS