一,方案
看了官方的文档,获取小程序码有三种,我采用的是第二种:生成数量不受限制的分享码。
对应的官方文档:https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/qrcode-link/qr-code/getUnlimitedQRCode.html
其中又分为https调用和云开发调用。
因为我用的是unicloud云开发,如果采用微信的云开发,还需要引入wx-server-sdk,然后要配置一堆东西,文档又不全,尝试了两次未果,就放弃了这种方案。
最后是采用的https调用的方式。
二,实现思路
【第一步】需要获取ACCESS_TOKEN值。
这种微信的接口,必须服务端调用,不能前端直接https进行调用。虽然在开发阶段能够调用成功,那是因为微信开发者工具-项目信息-本地设置中勾选了不校验合法域名导致的成功。当你发布体验版和正式版时是调用不通的。
所以,获取ACCESS_TOKEN必须在服务端直接调用微信接口获取。
官方文档:https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/access-token/auth.getAccessToken.html
实现的云对象代码:
// 云对象教程: https://uniapp.dcloud.net.cn/uniCloud/cloud-obj
// jsdoc语法提示教程:https://ask.dcloud.net.cn/docs/#//ask.dcloud.net.cn/article/129
module.exports = {
_before: function () { // 通用预处理器
},
async addCodeInfo(infoObj){
//获取access_token
const APPID='xxx'
const APPSECRET='xxx'
const URL = `https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${APPID}&secret=${APPSECRET}`
const requestOptions = {
method: 'GET',
dataType: 'json'
}
const res1 = await uniCloud.httpclient.request(URL,requestOptions)
const access_token=res1.data.access_token
return access_token
}
}
【第二步】需要利用ACCESS_TOKEN再调用微信的生成分享码的接口
这个接口依旧是微信的接口,所以依旧是需要在服务端发起。
于是,在上一步获取到access_token的基础上,继续调用获取分享码的接口:
// 云对象教程: https://uniapp.dcloud.net.cn/uniCloud/cloud-obj
// jsdoc语法提示教程:https://ask.dcloud.net.cn/docs/#//ask.dcloud.net.cn/article/129
module.exports = {
_before: function () { // 通用预处理器
},
//数据库中增加wifi信息,增加完毕后返回分享二维码
async addCodeInfo(infoObj){
//获取access_token
const APPID='wxe0bc57edf31dad80'
const APPSECRET='7e5f676a5fad20d044434792360c28d4'
const URL = `https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${APPID}&secret=${APPSECRET}`
const requestOptions = {
method: 'GET',
dataType: 'json'
}
const res1 = await uniCloud.httpclient.request(URL,requestOptions)
const access_token=res1.data.access_token
//由此id生成分享码
const codeUrl=`https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=${access_token}`
const codeOptions={
method:'POST',
data: JSON.stringify({
"scene":'id',
"page":'pages/index/index',
"check_path":false,
"width":500,
"env_version":'trial'//trial:体验版
}),
}
const res3 = await uniCloud.httpclient.request(codeUrl,codeOptions)
return res3
}
}
【第三步】获取到的分享码结果类型是buffer的二进制格式,需要转图片
如下图:
也就是,res.data是个buffer类型的数据,它有两个字段:data字段存储内容,type字段显示类型。
于是需要在服务端转成base64后再传给前端:
const buffer=res3.data
const result=buffer.toString('base64')
三,完整的代码实现
前端
<img :src="shareCode" alt="" >
<script>
export default {
data() {
return {
shareCode:'',
}
},
onLoad(options) {
this.getWeixinCode()
},
methods: {
//调用后端接口,生成小程序分享码
async getWeixinCode() { // 注意异步
const _this=this
const wifiCode = uniCloud.importObject('wifiCode') // 导入云对象
try {
const params={}
const res=await wifiCode.addCodeInfo(params)
console.log("++++",res)
this.shareCode="data:image/png;base64," + res
} catch (e) {
console.log(e)
}
}
}
}
</script>
后端:
主要就是wifiCode这个云对象:
// 云对象教程: https://uniapp.dcloud.net.cn/uniCloud/cloud-obj
// jsdoc语法提示教程:https://ask.dcloud.net.cn/docs/#//ask.dcloud.net.cn/article/129
module.exports = {
_before: function () { // 通用预处理器
},
//数据库中增加wifi信息,增加完毕后返回分享二维码
async addCodeInfo(infoObj){
//获取access_token
const APPID='xxx'
const APPSECRET='xxx'
const URL = `https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${APPID}&secret=${APPSECRET}`
const requestOptions = {
method: 'GET',
dataType: 'json'
}
const res1 = await uniCloud.httpclient.request(URL,requestOptions)
const access_token=res1.data.access_token
//由此id生成分享码
const codeUrl=`https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=${access_token}`
const codeOptions={
method:'POST',
data: JSON.stringify({
"scene":"23",
"page":'pages/index/index',
"check_path":false,
"width":500,
"env_version":'trial'//trial:体验版
}),
}
const res3 = await uniCloud.httpclient.request(codeUrl,codeOptions)
const buffer=res3.data
console.log("---响应--",buffer)
// const buf = new Buffer (buffer)
console.log("buffer转化",buffer.toString('base64'))
const result=buffer.toString('base64')
return result
}
}
四,坑点
1,微信的接口需要服务端调用
2,获取分享码的接口的post接口参数需要JSON.stringify处理一次
3,scenez只支持32位,一些特殊字符还不支持。
4,获取分享码的接口的access_token参数,必须放在url上,也就是和我代码中一样的写法。
5,本地开发完成后,云对象啥的需要上传部署后,体验版和真机调试才能用。并且,需要配置小程序的接口白名单。https://tcb-api.tencentcloudapi.com和
https://tcb-wbk382fznzzwna3-8chuc14d8e99.service.tcloudbase.com
6,获取分享码的接口,返回的是buffer二进制流,所以获取二维码的接口,我没有配置datatype这个参数,而是让它采用默认的值。获取到结果后还需要转化成base64才可以渲染在页面上。
总而言之,比较坑,但是我没哭。
呐,就这样吧~
希望对后续看到的小伙伴有所帮助~