微信公众号中的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 相关文章推荐
jQuery中live方法的重复绑定说明
Oct 21 Javascript
jQuery ajax serialize() 方法使用示例
Nov 02 Javascript
学习JavaScript编程语言的8张思维导图分享
Mar 27 Javascript
关于微信jssdk实现多图片上传的一点心得分享
Dec 13 Javascript
bootstrap日期控件问题(双日期、清空等问题解决)
Apr 19 Javascript
jquery实现简单实用的轮播器
May 23 jQuery
深入理解ES6 Promise 扩展always方法
Sep 26 Javascript
Vue自定义指令实现checkbox全选功能的方法
Feb 28 Javascript
JavaScript设计模式之代理模式实例分析
Jan 16 Javascript
vue-cli3使用mock数据的方法分析
Mar 16 Javascript
JS实现炫酷雪花飘落效果
Aug 19 Javascript
Electron+vue从零开始打造一个本地播放器的方法示例
Oct 27 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批量生成缩略图的代码
2008/07/19 PHP
关于IIS php调用com组件的权限问题
2012/01/11 PHP
php递归创建和删除文件夹的代码小结
2012/04/13 PHP
在你的网页中嵌入外部网页的方法
2007/04/02 Javascript
PNGHandler-借助JS让PNG图在IE下实现透明(包括背景图)
2007/08/31 Javascript
如何从jQuery的ajax请求中删除X-Requested-With
2013/12/11 Javascript
js闭包实例汇总
2014/11/09 Javascript
javascript强制点击广告的方法
2015/02/06 Javascript
jQuery实现给页面换肤的方法
2015/05/30 Javascript
详解vue组件化开发-vuex状态管理库
2017/04/10 Javascript
bootstrap switch开关组件使用方法详解
2017/08/22 Javascript
JS获取字符对应的ASCII码实例
2017/09/10 Javascript
Vue异步加载about组件
2017/10/31 Javascript
百度地图去掉marker覆盖物或者去掉maker的label文字方法
2018/01/26 Javascript
jQuery实现图片简单轮播功能示例
2018/08/13 jQuery
js作用域和作用域链及预解析
2019/04/11 Javascript
vue的滚动条插件实现代码
2019/09/07 Javascript
使用vue-cli3+typescript的项目模板创建工程的教程
2020/02/28 Javascript
[42:20]Winstrike vs VGJ.S 2018国际邀请赛淘汰赛BO3 第二场 8.23
2018/08/24 DOTA
简单介绍Python中的JSON使用
2015/04/28 Python
python获取目录下所有文件的方法
2015/06/01 Python
Python实现的简单dns查询功能示例
2017/05/24 Python
Python获取系统所有进程PID及进程名称的方法示例
2018/05/24 Python
python实现决策树分类
2018/08/30 Python
PyQT5 实现快捷键复制表格数据的方法示例
2020/06/19 Python
Python数据可视化实现漏斗图过程图解
2020/07/20 Python
HTML5 device access 设备访问详解
2018/05/24 HTML / CSS
导出HTML5 Canvas图片并上传服务器功能
2019/08/16 HTML / CSS
vue+django实现下载文件的示例
2021/03/24 Vue.js
详细的大学生创业计划书模板
2014/01/27 职场文书
2014年幼师工作总结
2014/11/22 职场文书
监察建议书
2015/02/04 职场文书
商场圣诞节活动总结
2015/05/06 职场文书
2015年共青团工作总结
2015/05/15 职场文书
房贷收入证明范本
2015/06/12 职场文书
Python 统计序列中元素的出现频度
2022/04/26 Python