突然发现,已经有将近一年的时间没有写博客了,在这一年之中,我想通了很多事,也做了一些改变,毕竟,即将30岁,诸多无奈无以言语。
言归正传,最近在做公众号后台以及vue页面相关的开发,最近的需求中,需要调用微信的扫一扫功能,但是在接入的过程中发现没有那么简单,需要介绍下微信提供给我们的weixin-js-sdk - npm(微信官方使用说明:https://www.npmjs.com/package/weixin-js-sdk)
首先大家需要明确的一点(因为我之前也有这个疑问),就是:vue接入微信扫一扫必须要后台配合开发,只在vue前端修改是无法使用扫一扫等相关功能的,因为这里微信官方服务需要校验相关值,具体的说明文档见官方附录1,我这里节选一些内容:
下面正文开始:
坑点1:
1.微信官方提供的教程是前端对接的方式,但是我们的项目使用的是vue+vantUI做的移动界面,所以在此处浪费了很长的时间。但是有一篇文章很给力,帮助我解决了导入问题:vue调用微信扫一扫(扫码),这里非常感谢作者,我们这里使用npm安装的时候,需要使用的命令,以及导入方式为:
// 下载安装命令
npm install weixin-jsapi --save
// 在man.js中引入 weixin-jsapi
import wx from "weixin-jsapi";
// 在man.js中注册 weixin-jsapi
Vue.prototype.wx = wx
具体的业务代码可以参照文章中的代码。
坑点2:在vue请求接口的时候,url需要动态获取当前的url,但是按照官方文档需要做一层处理,官方说明如下:
确保你获取用来签名的url是动态获取的,动态页面可参见实例代码中php的实现方式。
如果是html的静态页面在前端通过ajax将url传到后台签名,前端需要用js获取当前页面除去'#'hash部分的链接
(可用location.href.split('#')[0]获取,而且需要encodeURIComponent),
因为页面一旦分享,微信客户端会在你的链接末尾加入其它参数,如果不是动态获取当前链接,
将导致分享后的页面签名失败。
这里请求的时候,需要对url进行encode,后端对应需要进行decode。
坑点3:公众号配置js接口安全域名的时候需要注意两点:
1.域名结尾不要加斜杠
2.域名不要加http://
坑点4:vue页面需要加上wx.error,否则都不知道报错原因,上面简书的作者没有加这个,可能他比较仔细,设置的相关地方没有报错,而我研究了很久,加了这个提示之后才找到相关问题。
wx.error(function (res) {
alert("出错了:" + res.errMsg);//这个地方的好处就是wx.config配置错误,会弹出窗口哪里错误,然后根据微信文档查询即可。
});
坑点5:既然我们前面提到了编码url,这里就要在java后端接收的时候,进行decode,这里我使用的是java第三方框架,WxJava传送门,这里非常感谢作者的无私奉献,框架是真的好用,帮我们节省了大量时间和精力,比如后台刷新AccessToken等操作,全部由框架完成,同时框架支持多个AppId随意切换,功能强大,具体的代码如下:
@GetMapping("/getJsapiSignature")
public GeneralReturnBean<WxJsapiSignature> createJsapiSignature(@RequestParam String url, @RequestParam String appId) throws WxErrorException {
String randomStr = "";
String jsapiTicket = "";
String signature = "";
long timestamp = System.currentTimeMillis() / 1000;
boolean isOk = true;
try {
url = URLDecoder.decode(url, "UTF-8");
AppIdManagerUtil.switchAppId(wxCustomAppIdController, wxService, "", appId);
randomStr = RandomUtils.getRandomStr();
jsapiTicket = wxService.getJsapiTicket();
signature = SHA1.genWithAmple("jsapi_ticket=" + jsapiTicket, "noncestr=" + randomStr, "timestamp=" + timestamp, "url=" + url);
CommonUtil.writeNormalInfo("appId=" + wxService.getWxMpConfigStorage().getAppId() + ",jsapi_ticket=" + jsapiTicket +
",noncestr=" + randomStr + ",timestamp=" + timestamp + ",url=" + url);
} catch (Exception e) {
isOk = false;
CommonUtil.writeErrorInfo("getJsapiSignature接口报错-------" + ExceptionUtils.getStackTrace(e));
}
GeneralReturnBean<WxJsapiSignature> generalReturnBean = new GeneralReturnBean<>();
if (isOk) {
generalReturnBean.setCode(0);
generalReturnBean.setMessage("");
generalReturnBean.setData(WxJsapiSignature
.builder()
.appId(wxService.getWxMpConfigStorage().getAppId())
.timestamp(timestamp)
.nonceStr(randomStr)
.url(url)
.signature(signature)
.build());
} else {
generalReturnBean.setCode(-1);
generalReturnBean.setMessage("获取JsapiSignature失败,请联系后台开发查看日志!");
generalReturnBean.setIssuccess(false);
}
return generalReturnBean;
}
坑点5:invalid url domain报错,解决:
参照第二点,我这边的原因是,域名结尾加了斜杠,去掉就可以了。。。