方式1:静态 html 引入
<script src="https://res2.wx.qq.com/open/js/jweixin-1.6.0.js"></script>
方式二:vue 单页面
// 可以在主入口文件 index.html 内引入
<script src="https://res2.wx.qq.com/open/js/jweixin-1.6.0.js"></script>
// 使用页面通过 window.wx 方式访问 wx 模块
或者安装依赖使用
// 安装
npm install weixin-js-sdk
//引入
import wx from 'weixin-js-sdk'
wx.config({
debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: '', // 必填,公众号的唯一标识
timestamp: res.data.timestamp, // 必填,生成签名的时间戳
nonceStr: res.data.nonceStr, // 必填,生成签名的随机串
signature: res.data.cardSign, // 必填,签名
jsApiList: ['scanQRCode']
});
timestamp,nonceStr,signature 重要信息请根据自己的公众号信息去获取。需要注意的是 debug 调试的时候,设置为 true ,会自动弹出配置成功或失败信息,调试时可以借助它。
var ua = navigator.userAgent.toLowerCase()
var isWeixin = ua.indexOf('micromessenger') !== -1
//做了一个判断处理,检查只有微信浏览器,其他浏览器不可以调用
if (!isWeixin) {
alert('请用微信打开连接,才可使用扫一扫')
}
wx.scanQRCode({
needResult: 1, // 默认为0,扫描结果由微信处理,1则直接返回扫描结果,
scanType: ['qrCode', 'barCode'], // 可以指定扫二维码还是一维码,默认二者都有
success: function (res: { resultStr: any; }) {
const serial = (res.resultStr).split(",");
cardNum.value = serial[serial.length - 1];//直接获取结果
},
fail: function (res: { errMsg: string | string[]; }) {
if (res.errMsg.indexOf('function_not_exist') > 0) {
alert('当前版本过低,请进行升级')
}
}
})
先声明一下,我的项目是 vue 单页面。
真机测试的时候,一直在提示:
errMsg:config:invalid signature
中文叫做签名无效。
查找原因是因为我的签名获取来和官方 微信 js 接口签名校验工具获取来的数据不一样,很明显获取的签名有问题,是因为我的 url 配置和前端调起接口的 url 不一致造成的
苹果手机真机测试,提示错误信息为:
the permission value is offline verifying
翻译为中文:权限值正在脱机验证
这个错误原因是 config 没有正确执行。
又继续去检查签名的问题,最后发现是后台接口字段写错了,欲哭无泪,总之还是签名信息错误。
用安卓测试的时候,竟然好了,完美展示扫码结果,以为要好了。使用 ios 测试的时候,竟然发现点击的时候没有任何反应。
找了半天原因,是因为 window.location.href 不同造成的。
alert(window.location.href)
测试结果:
安卓:https://hp.******.net/
IOS:https://hp.******.net//
IOS 手机就是因为 url 与签名配置处的 url 不同,所以导致 config 执行失败。究其原因是因为我的 vue-router 是 hash 模式。
解决方案:把我的 hash 模式换成 history 模式。记得后台也需要配置 nginx 。
当 IOS 能调起接口的那一刻,我以为要成功了,哪知道它就是要与 安卓 与众不同,扫码之后没有任何反应,但是如果你快速地连续多扫几次就会出现结果。加个延时解决
let isAndriod = ua.indexOf('andriod') !== -1
window.wx.scanQRCode({
needResult: 1, // 默认为0,扫描结果由微信处理,1则直接返回扫描结果,
scanType: ['qrCode', 'barCode'], // 可以指定扫二维码还是一维码,默认二者都有
success: function (res) {
// 扫码成功,跳转到二维码指定页面(res.resultStr为扫码返回的结果)
// location.href = res.resultStr;
var scan = res.resultStr
if (isAndriod) {
_this.$router.push({ path: '/exam_car', query: { id: scan } })
} else {
setTimeout(() => {
_this.$router.push({ path: '/exam_car', query: { id: scan } })
}, 500)
}
},
error: function (res) {
if (res.errMsg.indexOf('function_not_exist') > 0) {
alert('当前版本过低,请进行升级')
}
},
})
可能存在问题:
1、iOS设备扫码正常,Android设备扫码后没反应
2、Android设备扫码正常,iOS设备扫码后没反应
原因:微信开发文档并没有说清楚,其实在微信后台可能是维护了2个接口, 或者是对设备类型进行了区别,总之在回调函数中返回的结果封装对象并不是同一个, 所以这要求我们也进行相应的处理, 不然就会出现上面这种默认奇妙的问题。
IOS 返回结果:
{
err_Info: 'success',
resaultStr: 'XX',
errMsg: 'scanQRCode:ok'
}
Android 结果:
{
resaultStr: 'XX',
errMsg: 'scanQRCode:ok'
}
现在改为登录之后才可以扫码,路由修改了一下,先在登录页登录成功之后,再进入扫码页,后台也同步修改了 url 地址,修改完测试发现:
安卓的一切正常。
苹果错误提示:noPermissionJsApi:[],errMsg:“config:ok”。
确定之后有一个错误提示:errMsg:scanQRCode:the perssion value is offline verifying。
$router.push 的跳转影响了我的 url ,在 IOS 上的 push 跳转不能写入浏览器的地址栏,但是安卓可以,导致安卓和 ios 跳转之后的地址不同,所以 ios 失败了。
解决方法:
$router.push('/i')
//修改成了
window.location = window.location.protocol + '//' + window.location.host + '/i'
微信官方开发文档:
https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html#4