近期在写一个微信公众号网站,需要用到微信扫一扫功能。去微信开发文档发现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
模块:
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
的值:
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)
})
到这里可以将上面两步封装成一个函数:
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中
创建数据模型:
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);
插入或更新数据:
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
})
})
}
})
}
每个一小时刷新数据:
setInterval(() => {
resetTicket()
}, 1000 * 60 * 60)
生成签名和返回路由数据
签名算法官方文档:https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html#62
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
}
})
})
})
前端获取数据并调用微信扫一扫接口
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)
}
})
到这里就可以调用微信扫一扫功能了。
11 条评论
你的文章内容非常卖力,让人点赞。 http://www.55baobei.com/9nxhjwiOm8.html
你的文章充满了欢乐,让人忍不住一笑。 https://www.yonboz.com/video/9603.html
《猪猪侠之超星萌宠4》国产动漫高清在线免费观看:https://www.jgz518.com/xingkong/43938.html
《2024河北广播电视台非遗元宵晚会》大陆综艺高清在线免费观看:https://www.jgz518.com/xingkong/22911.html
复古传奇私服:畅游老游戏的时光之旅:https://501h.com/jingpin/4310.html
文章写的很好啊,赞(ㆆᴗㆆ),每日打卡~~
又发现一个好站,收藏了~以后会经常光顾的ヾ(≧∇≦*)ゝ
赞!混个脸熟,博客真好看ヾ(≧∇≦*)ゝ
文章写的不错,加油~
1
1