微信公众号中的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 相关文章推荐
javascript中实现兼容JAVA的hashCode算法代码分享
Aug 11 Javascript
Javascript实现Web颜色值转换
Feb 05 Javascript
jQuery插件bgStretcher.js实现全屏背景特效
Jun 05 Javascript
js控制div层的叠加简单方法
Oct 15 Javascript
JavaScript 限制文本框不可输入英文单双引号的方法
Dec 20 Javascript
js获取一组日期中最近连续的天数
May 25 Javascript
深究AngularJS如何获取input的焦点(自定义指令)
Jun 12 Javascript
基于js原生和ajax的get和post方法以及jsonp的原生写法实例
Oct 16 Javascript
JS中获取 DOM 元素的绝对位置实例详解
Apr 23 Javascript
微信小程序实现提交input信息到后台的方法示例
Jan 19 Javascript
vue请求本地自己编写的json文件的方法
Apr 25 Javascript
详解如何探测小程序返回到webview页面
May 14 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
一个php作的文本留言本的例子(一)
2006/10/09 PHP
劣质的PHP代码简化
2010/02/08 PHP
PHP弹出对话框技巧详细解读
2015/09/26 PHP
使用XHProf查找PHP性能瓶颈的实例
2017/12/13 PHP
详解php与ethereum客户端交互
2018/04/28 PHP
Yii2框架控制器、路由、Url生成操作示例
2019/05/27 PHP
Javascript 解疑
2009/11/11 Javascript
情人节专属 纯js脚本1k大小的3D玫瑰效果
2012/02/11 Javascript
深入理解javascript的执行顺序
2014/04/04 Javascript
浅谈页面装载js及性能分析方法
2014/12/09 Javascript
jQuery中[attribute^=value]选择器用法实例
2014/12/31 Javascript
JavaScript操作HTML DOM节点的基础教程
2016/03/11 Javascript
node.js连接mongoDB数据库 快速搭建自己的web服务
2016/04/17 Javascript
Bootstrap前端开发案例二
2016/06/17 Javascript
AngularJS使用ng-inlude指令加载页面失败的原因与解决方法
2017/01/19 Javascript
three.js加载obj模型的实例代码
2017/11/10 Javascript
jQuery实现的页面详情展开收起功能示例
2018/06/11 jQuery
小程序实现搜索框功能
2020/03/26 Javascript
jQuery实现轮播图效果
2019/11/26 jQuery
[01:45]2014DOTA2 TI预选赛预选赛 大神专访第二弹!
2014/05/20 DOTA
[01:12:27]EG vs Secret 2018国际邀请赛淘汰赛BO3 第二场 8.22
2018/08/23 DOTA
浅析Python编写函数装饰器
2016/03/18 Python
Python实现的堆排序算法原理与用法实例分析
2017/11/22 Python
安装Pycharm2019以及配置anconda教程的方法步骤
2019/11/11 Python
Python字典深浅拷贝与循环方式方法详解
2020/02/09 Python
tensorflow2.0的函数签名与图结构(推荐)
2020/04/28 Python
html5 postMessage前端跨域并前端监听的方法示例
2018/11/01 HTML / CSS
有针对性的求职自荐信
2013/11/14 职场文书
产品工艺师的岗位职责
2013/11/15 职场文书
21岁生日感言
2014/02/27 职场文书
爱牙日活动总结
2014/08/29 职场文书
六查六看自检自查剖析材料
2014/10/14 职场文书
学生检讨书如何写
2014/10/30 职场文书
2015年卫生监督工作总结
2015/05/21 职场文书
vue3引入highlight.js进行代码高亮的方法实例
2022/04/08 Vue.js
win10系统计算机图标怎么调出来?win10调出计算机图标的方法
2022/08/14 数码科技