Loading... 近期在写一个微信公众号网站,需要用到微信扫一扫功能。去微信开发文档发现JS-SDK可以实现这个功能,调用接口需要先获取 `access_token`和 `jsapi_ticket`,但是微信对这两个接口每天的调用次数都有限制。考虑到 `access_token`和 `jsapi_ticket`都会在生成后的7200秒内有效,可以将 `jsapi_ticket`存在数据库中,然后每小时刷新一次数据,这样可以减少接口的调用次数,在此记录一下实现的过程。 ## 获取access_token > 官方文档:https://developers.weixin.qq.com/doc/offiaccount/Basic_Information/Get_access_token.html 通过接口https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET获取 `access_token`值,APPID和APPSECRET可以在公众号开发信息中找到。 这里使用的是 `request-promise`模块: ```javascript const request = require("request-promise"); const wxConfig = { AppID: 'xxx', AppSecret: 'xxx' } let url = `https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${wxConfig.AppID}&secret=${wxConfig.AppSecret}`; request(url).then(res => { console.log(JSON.parse(res).access_token); }) ``` ## 获取jsapi_ticket 通过接口https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi获取 `jsapi_ticket`的值: ```javascript let url = `https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=${JSON.parse(res).access_token}&type=jsapi` request(url).then(res => { resolve(JSON.parse(res).ticket) }) ``` 到这里可以将上面两步封装成一个函数: ```javascript function getTicket(wxConfig) { return new Promise((resolve, reject) => { let url = `https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${wxConfig.AppID}&secret=${wxConfig.AppSecret}`; request(url).then(res => { url = `https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=${JSON.parse(res).access_token}&type=jsapi` request(url).then(res => { resolve(JSON.parse(res).ticket) }) }) }) } ``` ## 将jsapi_ticket存储在MongoDB中 创建数据模型: ```javascript const mongoose = require("mongoose"); const Schema = mongoose.Schema; const WxTokenSchema = new Schema({ jsapi_ticket: { required: true, type: String }, }); module.exports = Wxtoken = mongoose.model("wxToken", WxTokenSchema); ``` 插入或更新数据: ```javascript const WxToken = require("../../models/WxToken"); function resetTicket() { WxToken.find().then(data => { if (data.length) { getTicket(wxConfig).then(ticket => { data[0].jsapi_ticket = ticket data[0].save() }) } else { getTicket(wxConfig).then(ticket => { WxToken.create({ 'jsapi_ticket': ticket }) }) } }) } ``` 每个一小时刷新数据: ```javascript setInterval(() => { resetTicket() }, 1000 * 60 * 60) ``` ## 生成签名和返回路由数据 > 签名算法官方文档:https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html#62 ```javascript const crypto = require('crypto'); router.get('/', function (req, res) { WxToken.findOne().then(data => { let noncestr = Math.random() * 10000000 let jsapi_ticket = data.jsapi_ticket let timestamp = new Date().getTime() let url = 'http://test.no0a.cn/' let string = `jsapi_ticket=${jsapi_ticket}&noncestr=${noncestr}×tamp=${timestamp}&url=${url}` let signature = crypto.createHash('sha1').update(string).digest('hex') res.json({ status: 200, data: { appId: wxConfig.AppID, timestamp, noncestr, signature } }) }) }) ``` ## 前端获取数据并调用微信扫一扫接口 ```javascript wx.config({ debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。 appId: '', // 必填,公众号的唯一标识 timestamp: '', // 必填,生成签名的时间戳 nonceStr: '', // 必填,生成签名的随机串 signature: '', // 必填,签名 jsApiList: ['scanQRCode'] // 必填,需要使用的JS接口列表 }); wx.scanQRCode({ needResult: 1, // 默认为0,扫描结果由微信处理,1则直接返回扫描结果, scanType: ["qrCode", "barCode"], // 可以指定扫二维码还是一维码,默认二者都有 success(res) { console.log(res.resultStr) } }) ``` 到这里就可以调用微信扫一扫功能了。 最后修改:2020 年 08 月 04 日 04 : 49 PM © 允许规范转载 赞赏 如果觉得我的文章对你有用,请随意赞赏 ×Close 赞赏作者 扫一扫支付 支付宝支付 微信支付
4 条评论
文章写的很好啊,赞(ㆆᴗㆆ),每日打卡~~
又发现一个好站,收藏了~以后会经常光顾的ヾ(≧∇≦*)ゝ
赞!混个脸熟,博客真好看ヾ(≧∇≦*)ゝ
文章写的不错,加油~