获取小程序码的主要流程是:通过小程序的APPID和APPsecret来获取access_token,然后通过access_token来调用微信提供的获取小程序二维码的接口,然后把返回的二进制流保存成图片,并返回地址给前端。
这边有个要注意的是,access_token有两小时的过期时间,需定期来获取,自己的主要思路是:获取access_token成功后记录下此时的时间戳(设为time2)保存起来,然后前端每次调用获取小程序码的接口时记录下当前的时间戳(设为time1);然后两次做对比如果是大于7200秒的话说明已经过期,需要重新获取access_token。主要代码如下:
app.get('/api/getcode',function(req,res){ //获取小程序二维码
var time1 = (new Date()).getTime();
if(!time2 && (time1-time2)>7000){ //如果access_token过期了重新请求获取
request('https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=wx5e5a1e04aa589faa&secret=cd022822b5266daedbc0870de1570495',function(error,response,body){
if(!error && response.statusCode == 200){ //请求成功处理逻辑
var data = JSON.parse(body);
time2 = (new Date()).getTime();
access_token = data.access_token;
console.log(data)
//console.log(data.access_token);
getwxcode(access_token,function(){
res.json({stasus:true,imgurl:'images/qcode.png'});
}); //获取二维码
}
})
}else{ //没过期直接获取access_token
console.log('else------')
getwxcode(access_token,function(){
res.json({stasus:true,imgurl:'images/qcode.png'});
}); //获取二维码
}
})
接下来就是通过access_token来获取小程序码,代码如下:
function getwxcode(access_token,cb){ //通过access_token获取小程序二维码
//方法1:利用http请求
data = {
path: "pages/index/index",//二维码默认打开小程序页面
scene: "111",//打开页面时携带的参数
width: 300,
auto_color: false
};
data = JSON.stringify(data);
var options = {
method: "POST",
host: "api.weixin.qq.com",
path: "/cgi-bin/wxaapp/createwxaqrcode?access_token="+access_token,
headers: {
"Content-Type": "application/json",
"Content-Length": data.length
}
};
var req = http.request(options, function (res) {
res.setEncoding("binary");
var imgData = "";
res.on('data', function (chunk) {
imgData += chunk;
});
res.on("end", function () {
fs.writeFile("./wx_qcode3.jpg", imgData, "binary", function (err) {
if (err) {
console.log("down fail");
}
console.log("down success");
cb&&cb();
});
});
});
req.write(data);
req.end();
//方法2: 利用request模块发起请求
/*var postData = {
path: "pages/index/index",//二维码默认打开小程序页面
scene: "111",//打开页面时携带的参数
width: 300,
auto_color: false
}
postData = JSON.stringify(postData);
var myP = new Promise(function (resolve, reject) { //由于request pipe是异步下载图片的,需要同步的话需添加一个promise
var stream = request({
method: 'POST',
url: 'https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=' + access_token,
body: postData
}).pipe(fs.createWriteStream('./images/qcode.png'));
stream.on('finish', function () {
//resolve("OK123");
cb&&cb();
});
});*/
}
我这边保存完后返回的路径我是写死了,可以写个函数把自己保存的路径和文件名返回给前端。
完整代码如下:
var express = require('express');
var app = express();
var http = require('http');
var fs = require('fs');
var request = require('request');
app.use(express.static('./')); //设置访问静态资源
var appid = '自己的小程序APPID',appsecret = '自己的小程序秘钥'; //小程序的APPID和APPsecret
app.get('/',function(req,res){
res.send('hello world');
})
var time2 = 0,access_token = '';
app.get('/api/getcode',function(req,res){ //获取小程序二维码
var time1 = (new Date()).getTime();
if(!time2 && (time1-time2)>7000){ //如果access_token过期了重新请求获取
request('https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=wx5e5a1e04aa589faa&secret=cd022822b5266daedbc0870de1570495',function(error,response,body){
if(!error && response.statusCode == 200){ //请求成功处理逻辑
var data = JSON.parse(body);
time2 = (new Date()).getTime();
access_token = data.access_token;
console.log(data)
//console.log(data.access_token);
getwxcode(access_token,function(){
res.json({stasus:true,imgurl:'images/qcode.png'});
}); //获取二维码
}
})
}else{ //没过期直接获取access_token
console.log('else------')
getwxcode(access_token,function(){
res.json({stasus:true,imgurl:'images/qcode.png'});
}); //获取二维码
}
})
function getwxcode(access_token,cb){ //通过access_token获取小程序二维码
//方法1:利用http请求
data = {
path: "pages/index/index",//二维码默认打开小程序页面
scene: "111",//打开页面时携带的参数
width: 300,
auto_color: false
};
data = JSON.stringify(data);
var options = {
method: "POST",
host: "api.weixin.qq.com",
path: "/cgi-bin/wxaapp/createwxaqrcode?access_token="+access_token,
headers: {
"Content-Type": "application/json",
"Content-Length": data.length
}
};
var req = http.request(options, function (res) {
res.setEncoding("binary");
var imgData = "";
res.on('data', function (chunk) {
imgData += chunk;
});
res.on("end", function () {
fs.writeFile("./wx_qcode3.jpg", imgData, "binary", function (err) {
if (err) {
console.log("down fail");
}
console.log("down success");
cb&&cb();
});
});
});
req.write(data);
req.end();
//方法2: 利用request模块发起请求
/*var postData = {
path: "pages/index/index",//二维码默认打开小程序页面
scene: "111",//打开页面时携带的参数
width: 300,
auto_color: false
}
postData = JSON.stringify(postData);
var myP = new Promise(function (resolve, reject) { //由于request pipe是异步下载图片的,需要同步的话需添加一个promise
var stream = request({
method: 'POST',
url: 'https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=' + access_token,
body: postData
}).pipe(fs.createWriteStream('./images/qcode.png'));
stream.on('finish', function () {
//resolve("OK123");
cb&&cb();
});
});*/
}
var server = app.listen(8081,function(){
var host = server.address().address;
var port = server.address().port;
console.log('应用实例,访问地址为:http://%s:%s',host,port);
})
这边获取二维码的时候用了两种方法去请求接口,奇怪的是两种方法获取的二维码却是不一样的,方法1保存下来是矩形的,方法2是菊花型。(不知道是什么原因。。。)
最后我的项目是vue项目,所以前端只要配置好反向代理,然后通过axios模块来发起请求就可以了,具体效果如下: