微信公众号中的JSSDK接入及invalid signature等常见错误问题分析(全面解析)


Posted in Javascript onApril 11, 2020

最近在搞微信公众号开发,进行到网页开发部分被坑了一天,最坑的问题就是invalid signature,而网上大部分解答这个问题的都没有说清楚,都直接丢文档。博主认为这样很不好。本文是博主结合自身遇到的问题所写,整个流程跟问题都很详细,虽然排版可能有点不好。但是绝对对遇到类似问题的朋友有所帮助。请认真看下去

一、绑定JS接口安全域名

生产号绑定方法:登录微信公众平台进入“公众号设置”的“功能设置”里填写“JS接口安全域名”。
测试号绑定方法:进入测试号管理页面,找到JS接口安全域名项绑定
JS接口安全域名官方说法是:开发者可在该域名下调用微信开放的JS接口
域名格式:如果你的项目域名是http://test.domain.com,那么JS接口安全域名为test.domain.com。切记!
域名绑定失败或者域名不存在会报错误:invalid url domain

二、引入微信js文件

引入方法:在需要调用JS接口的页面引入JS文件,用script标签引入即可
JS文件路径:http://res.wx.qq.com/open/js/jweixin-1.2.0.js(支持https)

三、通过wx.config接口注入权限验证

1、每个需要使用jssdk的页面都要使用config接口注入配置信息,wx.config调用方法如下:

wx.config({
 debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
 appId: '', // 必填,公众号的唯一标识
 timestamp: , // 必填,生成签名的时间戳,精确到秒
 nonceStr: '', // 必填,生成签名的随机串
 signature: '',// 必填,签名
 jsApiList: [] // 必填,需要使用的JS接口列表,例如:['chooseImage','previewImage','uploadImage']
})

其中appId,timestamp,nonceStr,signature必须从后台获取

四、后台生成并返回前端所需参数

1、jsapi_ticket

jsapi_ticket是公众号用于调用js接口的临时票据。有效期7200秒,跟公众号普通access_token一样,必须全局缓存起来,因为这个ticket获取次数有限,超过次数将无法使用。建议设置缓存时间为7198秒,因为当请求微信端生成jsapi_ticket返回给后台保存这个动作需要时间,如果设置7200秒,实际上最后一两秒时,缓存里面还存在,但实际在微信那边已经过期了,再拿这个ticket会出错。生成jsapi_ticket如下:

(1)获取普通access_token(GET请求): 

https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET

(2)用第一步获取的access_token使用GET请求获取jsapi_ticket

https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi

正确获取信息如下:

{
"errcode":0,
"errmsg":"ok",
"ticket":"bxLdikRXVbTPdHSM05e5u5sUoXNKd8-41ZO3MhKoyN5OfkWITDGgnr2fwJ0m9E8NYzWKVZvdVtaUgWvsdshFKA",
"expires_in":7200
}

2、生成签名(signature)

签名规则:
1、参与签名的字段包括noncestr(随机字符串), 有效的jsapi_ticket, timestamp(时间戳), url(当前网页的URL,不包含#及其后面部分)。
2、对所有待签名参数按照字段名的ASCII 码从小到大排序(字典序,sort()即可)后,使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串(string)。
3、使用sha1加密拼接成的字符串string。
注意:字段名和字段值都要使用原值,不要进行url转义

参与的字段示例:

noncestr=Wm3WZYTPz0wzccnW
jsapi_ticket=sM4AOVdWfPE4DxkXGEs8VMCPGGVi4C3VM0P37wVUCFvkVAy_90u5h9nbSlYy3-Sl-HhTdfl2fzFy1AOcHKP7qg
timestamp=1414587457
url=http://mp.weixin.qq.com?params=value

拼接完成的字符串:

jsapi_ticket=sM4AOVdWfPE4DxkXGEs8VMCPGGVi4C3VM0P37wVUCFvkVAy_90u5h9nbSlYy3-Sl-HhTdfl2fzFy1AOcHKP7qg&noncestr=Wm3WZYTPz0wzccnW×tamp=1414587457&url=http://mp.weixin.qq.com?params=value

使用sha1加密后的signature:

0f9de62fce790f9a083d5c99e95740ceb90c27ed

3、签名生成完后将appId、timestamp、nonceStr、signature一起返回到前端。格式示例:

{
	appId:appId,
	timestamp:timestamp,
	nonceStr: noncestr,
	signature: signature
}

前端拿到值后,写入到wx.config中相应字段即可

注意:

1、前端wx.config配置中的nonceStr字段名称的's'是大写。但是后台生成签名的noncestr字段的‘s'是小写,千万要注意,博主在这里浪费了不少时间。???/p>

2、时间戳(timestamp)值要记住精确到秒,不是毫秒。

3、生成签名的url(使用jssdk的页面地址,这个页面地址可以在浏览器访问),包含“?”号后面的所有参数,不包含“#”号后面的值。

如果是静默授权或者授权页面同意授权后跳转到的页面,页面路径会添加两个参数:code和state。

即授权后跳转页面为http://redirect.page.com,则完整路径为

http://redirect.page.com?code=kdijafdhjaikeiu20kaiela&state=STATE。

那么生成签名的url必须为授权后跳转页面的完整路径。前端获取这个路径:location.href.split('#')[0]

注意注意:这里有个大坑。。如果前端使用ajax(使用jquery)获取wx.config配置所需的几个参数的值,可以这样做:

$.ajax({
	url: 'http://backend.com?fullUrl=' + location.href.split('#')[0], //这里的参数fullUrl是当前页面的完整url(除去#后面部分)
	type: 'GET',
	success: function(res) {
		//操作后台返回值
	}
})

后台要怎么操作前端传过来的query值呢?大家肯定一眼看出来 获取query中的fullUrl字段不就行了。

博主也是这么做的,请看博主后台代码(使用nodejs的koa框架)

let query = this.request.query;//获取查询字符串
let fullUrl = query.fullUrl;//获取查询字符串中的fullUrl字段

怎么样,有没有看出什么不对劲的地方?没有?

博主把所有后续的获取access_token、jsapi_ticket、计算签名、返回值到前端、前端wx.config配置好这些所有操作做完,信心满满的开始用测试号访问页面。结果直接弹出config: invalid signature(开启debug模式)。WTF ???

当然,搞这一行早就做好了遇到问题的心理准备。。。。开始排错呗。。

首先在后台将获取access_token、jsapi_ticket、计算签名的参数字典序排序后的字符串、sha1加密后的字符串全部console.log出来。

发现,没有错误的地方。那行,看来有可能是我代码那个地方写错了,或者签名算错了?

到微信在线接口调试把刚刚打印的计算签名的几个参数分别填好。生成。。。发现跟我的代码生成的是一样的。

结果博主是各种排错,各种百度,各种google。结果还是config: invalid signature...................................此处省略博主心里一万句话

又这样过了一个多小时,无果。。。。。。博主一脸颓废的到茶水间泡了杯咖啡。。提提神。。又回到了岗位,准备从头开始跑一遍再仔细看看。

从前端请求获取签名接口开始,博主打印了query的值。。也就是let query  = this.request.query的值。。结果发现。query值为:

{
	fullUrl: 'http://redirect.page.com?code=kdijafdhjaikeiu20kaiela',
	state: 'STATE'
}

好吧,问题在这里,有没有人早就看出来的?前面说过,微信网页授权后跳转的页面完整路径为

http://redirect.page.com?code=kdijafdhjaikeiu20kaiela&state=STATE

有没有注意路径最后面的'&state=STATE'。当我们把这个完整路径当做查询字符串传到后台的时候,因为没有对这个路径进行encodeURIComponent.所以后台将'&state=STATE'单独看成了一个查询字符串参数,问题点在这里。。

后来查看公众号文档发现'附录5-常见错误及解决方法'第六条有说明

问题解决

使用encodeURIComponent(location.href.split('#')[0])即可

五、调用接口

wx.config配置完成后会执行wx.ready方法,所有接口必须要在config返回结果之后操作。config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。当前页面要使用的接口,要写入到config配置中的jsApiList中

1、拍照或从手机相册中选图接口

document.getElementById('chooseImage').onclick = function(){
 wx.chooseImage({
 count: 1, // 默认9
 sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有
 sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
 success: function (res) {
 var localIds = res.localIds; // 返回选定照片的本地ID列表,localId可以作为img标签的src属性显示图片
 }
 });
}

六、常见问题

1、invalid url domain:

js接口安全域名错误。可以看看第一项

2、invalid signature:

要么是jsapi_ticket错误,要么是签名算法问题,要么是算法的参数有问题,注意noncestr中的's'是小写的。如果都是对的。那就是前端传的url有问题了。。。好好检查一下,不要像博主一样啊。。。。

3、permission denied:

这个问题一般是没有接口权限的问题,有的接口是要认证之后才可以使用,当然,测试号不会有这个问题

总结

到此这篇关于微信公众号中的JSSDK接入及invalid signature等常见错误问题分析(全面解析)的文章就介绍到这了,更多相关微信公众号JSSDK接入invalid signature错误内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
动态样式类封装JS代码
Sep 02 Javascript
Extjs Ext.MessageBox.confirm 确认对话框详解
Apr 02 Javascript
JavaScript DOM基础
Apr 13 Javascript
初步认识JavaScript函数库jQuery
Jun 18 Javascript
用Move.js配合创建CSS3动画的入门指引
Jul 22 Javascript
jQuery获取单选按钮radio选中值与去除所有radio选中状态的方法
May 20 jQuery
Vue实现百度下拉提示搜索功能
Jun 21 Javascript
详解vue.js下引入百度地图jsApi的两种方法
Jul 27 Javascript
Vue渲染过程浅析
Mar 14 Javascript
解决nuxt页面中mounted、created、watch执行两遍的问题
Nov 05 Javascript
react如何快速设置文件路径别名
Apr 28 Javascript
JS的深浅复制详细
Oct 16 Javascript
微信分享invalid signature签名错误踩过的坑
Apr 11 #Javascript
vue.js中使用微信扫一扫解决invalid signature问题(完美解决)
Apr 11 #Javascript
vue使用微信扫一扫功能的实现代码
Apr 11 #Javascript
Vue 中 template 有且只能一个 root的原因解析(源码分析)
Apr 11 #Javascript
vue搜索页开发实例代码详解(热门搜索,历史搜索,淘宝接口演示)
Apr 11 #Javascript
JavaScript实现轮播图特效
Apr 10 #Javascript
JavaScript实现图片伪异步上传过程解析
Apr 10 #Javascript
You might like
咖啡豆分级制度 咖啡豆等级分类 咖啡豆是按口感分类的吗?
2021/03/05 新手入门
PHP输出控制功能在简繁体转换中的应用
2006/10/09 PHP
php图片加中文水印实现代码分享
2012/10/31 PHP
深入探讨:Nginx 502 Bad Gateway错误的解决方法
2013/06/03 PHP
由php中字符offset特征造成的绕过漏洞详解
2017/07/07 PHP
thinkPHP5框架中widget的功能与用法详解
2018/06/11 PHP
PHP7新特性
2021/03/09 PHP
枚举的实现求得1-1000所有出现1的数字并计算出现1的个数
2013/09/10 Javascript
js操作table示例(个人心得)
2013/11/29 Javascript
关于Javascript作用域链的八点总结
2013/12/06 Javascript
深入分析原生JavaScript事件
2014/12/29 Javascript
完善的jquery处理机制
2016/02/21 Javascript
把多个JavaScript函数绑定到onload事件处理函数上的方法
2016/09/04 Javascript
使用bootstrap validator的remote验证代码经验分享(推荐)
2016/09/21 Javascript
AngularJS 限定$scope的范围实例详解
2017/06/23 Javascript
IScroll5实现下拉刷新上拉加载的功能实例
2017/08/11 Javascript
node中koa中间件机制详解
2017/08/22 Javascript
详解Webpack如何引入CDN链接来优化编译后的体积
2019/06/21 Javascript
js贪心算法 钱币找零问题代码实例
2019/09/11 Javascript
node.js express框架实现文件上传与下载功能实例详解
2019/10/15 Javascript
vue下的@change事件的实现
2019/10/25 Javascript
React冒泡和阻止冒泡的应用详解
2020/08/18 Javascript
Python2包含中文报错的解决方法
2018/07/09 Python
Python3中在Anaconda环境下安装basemap包
2018/10/21 Python
Python中如何导入类示例详解
2019/04/17 Python
pygame实现成语填空游戏
2019/10/29 Python
pymysql之cur.fetchall() 和cur.fetchone()用法详解
2020/05/15 Python
python分布式爬虫中消息队列知识点详解
2020/11/26 Python
Python用Jira库来操作Jira
2020/12/28 Python
html5自动播放mov格式视频的实例代码
2020/01/14 HTML / CSS
学习委员自我鉴定
2014/01/13 职场文书
党员活动日总结
2014/05/05 职场文书
护理工作个人总结
2015/03/03 职场文书
班干部学习委员竞选稿
2015/11/20 职场文书
导游词之麻姑仙境
2019/11/18 职场文书
JS前端使用canvas实现扩展物体类和事件派发
2022/08/05 Javascript