微信公众号H5在配置微信参数的时候提示 config:fail,Error: 系统错误错误码63002,invalid signature ,表示签名有问题。签名的影响因素很多,但对于前端,最大的影响因素就是url参数要给对。url参数需要注意的两个点:
1.需要公众号安全域名配置
[公众号平台 =>设置与开发 =>公众号设置 =>功能设置 =>JS接口安全域名]
注意配置的时候不需要加http和结尾斜杠!
2.url 不能写死,哈希部分不要,其他的包括参数全部都要传给后端。
签名这种是后端给的,但是前端也可以通过一些其他的方式自己算出签名:
1.从[公众号平台 =>设置与开发 =>开发 =>基本配置]获取开发者ID(AppID)和开发者密码(AppSecret)
2.通过微信公众平台接口调试工具( https://mp.weixin.qq.com/debug/cgi-bin/apiinfo )获取access_token
3.获取jsapi_ticket( https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi )
4.使用微信 JS 接口签名校验工具( https://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=jsapisign )计算签名
最后生成的签名和其他参数在wx.config()中调试即可。
JS-SDK说明文档:https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html
这是我第一次公众号开发,本以为看着微信官方文档直接复制粘贴就好了,没想到是我天真了,爬过一个坑又入一个坑!就这么一个简单的事,竟然搞了一下午,所以写了这篇文章,希望可以帮到大家!
第一步:引入 weixin-js-sdk
直接在 html 文件内,使用 script 引入:
或者
第二步:权限验证配置
timestamp,nonceStr,signature 重要信息请根据自己的公众号信息去获取。需要注意的是 debug 调试的时候,设置为 true ,会自动弹出配置成功或失败信息,调试时可以借助它。
第三步:调用扫一扫接口
我们在需要的按钮处,点击事件处开始调用扫码接口,如:
做了一个判断处理,检查只有微信浏览器,其他浏览器不可以调用:
第四步:真机测试
真机测试的时候,一直在提示:
errMsg:config:invalid signature
中文叫做签名无效。
查找原因是因为我的签名获取来和官方 微信 js 接口签名校验工具获取来的数据不一样,很明显获取的签名有问题,是因为我的 url 配置和前端调起接口的 url 不一致造成的。
第五步:苹果手机测试
苹果手机真机测试,提示错误信息为:
the permission value is offline verifying
翻译为中文:权限值正在脱机验证
这个错误原因是 config 没有正确执行。
又继续去检查签名的问题,最后发现是后台接口字段写错了,欲哭无泪,总之还是签名信息错误。
第六步:安卓正常,苹果点击无反应
用安卓测试的时候,竟然好了,完美展示扫码结果,以为要好了。使用 ios 测试的时候,竟然发现点击的时候没有任何反应。
找了半天原因,是因为 window.location.href 不同造成的。
测试结果:
安卓:https://hp.******.net/
IOS:https://hp.******.net//
IOS 手机就是因为 url 与签名配置处的 url 不同,所以导致 config 执行失败。究其原因是因为我的 vue-router 是 hash 模式。
解决方案:把我的 hash 模式换成 history 模式。记得后台也需要配置 nginx 。
第七步:IOS 扫码无反应
当 IOS 能调起接口的那一刻,我以为要成功了,哪知道它就是要与 安卓 与众不同,扫码之后没有任何反应,但是如果你快速地连续多扫几次就会出现结果。
你就说要命不?网上查找了半天,看见有的人说有延时,最后想干脆加个延时算了。
果然加了延时之后就好了。
第八步:扫码结果处理
可能存在问题:
1、iOS设备扫码正常,Android设备扫码后没反应
2、Android设备扫码正常,iOS设备扫码后没反应
原因 :微信开发文档并没有说清楚,其实在微信后台可能是维护了2个接口, 或者是对设备类型进行了区别,总之在 回调 函数中返回的结果封装对象并不是同一个, 所以这要求我们也进行相应的处理, 不然就会出现上面这种默认奇妙的问题。
IOS 返回结果:
Android 结果:
第九步:修改路由
本以为 苹果安卓手机都能够正常扫码,没问题了。但是领导换需求了,之前是扫码放到外边,可以匿名扫。现在要修改成登录之后才可以扫码。
我就把路由修改了一下,先在登录页登录成功之后,再进入扫码页,后台也同步修改了 url 地址,修改完测试发现:
安卓的一切正常。
苹果手机坏了!
奔溃了,看看错误提示:noPermissionJsApi:[],errMsg:"config:ok"。
确定之后有一个错误提示。
errMsg:scanQRCode:the perssion value is offline verifying
一顿百度猛如虎,半天原地打转转!
有前边一次经验教训,我就又去找地址的原因。最后发现是竟然 $router.push 的跳转影响了我的 url ,在 IOS 上的 push 跳转不能写入浏览器的地址栏,但是安卓可以,导致安卓和 ios 跳转之后的地址不同,所以 ios 失败了。
解决办法:
此时就正常运行了。这下满足项目要求了,不会再出什么幺蛾子了!
微信官方开发文档:https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html#4
确认签名算法正确,可用t=jsapisign页面工具进行校验。也就是你自己后台生成签名要和微信校验算法生成的签名一致才可以(可能大小写不同)。注意:签名生成规则如下:参与签名的字段包括有效的jsapi_ticket(获取方式详见微信JSSDK文档),noncestr(随机字符串,由开发者随机生成),timestamp(由开发者生成的当前时间戳),url(当前网页的URL,不包含#及其后面部分。注意:对于没有只有域名没有path的URL,浏览器会自动加上/作为path,如打开/)。特别注意:你在利用参数生成签名的时候,要对所有待签名参数按照字段名的ASCII码从小到大排序(字典序)后,使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串string1。这里需要注意的是所有参数名均为小写字符。我的最开始的错误就是没有注意到生成签名的那几个参数要按照key=value的样式连接成一个字符串,然后在sha1加密生成。/****Java写的参数拼接算法***/String[]paramArr=newString[]{"jsapi_ticket="+jsapi_ticket,"timestamp="+timestamp,"noncestr="+nonce,"url="+jsurl}Arrays.sort(paramArr)//将排序后的结果拼接成一个字符串Stringcontent=paramArr[0].concat("&"+paramArr[1]).concat("&"+paramArr[2]).concat("&"+paramArr[3])System.out.println("拼接之后的content为:"+content)确认config中nonceStr(js中驼峰标准大写S),timestamp与用以签名中的对应noncestr,timestamp一致。确认url是页面完整的url(请在当前页面alert(location.href.split('#')[0])确认),包括'http(s)://'部分,以及'?'后面的GET参数部分,但不包括'#'hash后面的部分。确认config中的appid与用来获取jsapi_ticket的appid一致。确保一定缓存access_token和jsapi_ticket。确保你获取用来签名的url是动态生成的,动态页面可参见实例代码中php的实现方式。如果是html的静态页面在前端通过ajax将url传到后台签名,前端需要用js获取当前页面除去'#'hash部分的链接(可用location.href.split('#')[0]获取),因为页面一旦分享,微信客户端会在你的链接末尾加入其它参数,如果不是动态获取当前链接,将导致分享后的页面签名失败。