为什么要用云函数来做这个?
- 前端一条龙不求人(后端)
- 利用官方资源来快速解决问题,白piao不香吗?
之前也有不少人分享过云函数生成小程序码的方法,这里我为大家总结下不同方法的区别和优缺点~
开盖食用思路:
小程序端请求 --> 云函数API小程序 --> 返回图片的buffer --> 把buffer转化成图片
1、云函数部分
// 云函数入口文件
const cloud = require('wx-server-sdk')
cloud.init()
exports.main = async (event, context) => {
try {
const result = await cloud.openapi.wxacode.get({
path: event.url, //传入需要配置的url,但是新版本不能传参param
width: 300
})
console.log(result)
return result
} catch (err) {
console.log(err)
return err
}
}
新建一个云函数名字为getWxacode,示例是openapi.wxacode.get的方法,这个参数可以直接跳转小程序内部对应的page。
注意:
与 wxacode.createQRCode 总共生成的码数量限制为 100,000,如果你需要大量生成码,请谨慎调用。且新版本只能传path,不能传参param~
2、页面部分
Page({
data: {
imgUrl: "" //图片地址
},
getWxacode() {
wx.cloud.init();
let self = this;
wx.showLoading({
title: '请求云函数'
})
// 调用云函数 获取 内容
wx.cloud.callFunction({
name: 'getWxacode',
data: {
url: "pages/home/index"
},
success: res => {
console.log('云函数调用成功', res);
let bufferImg = "data:image/png;base64," + wx.arrayBufferToBase64(res.result.buffer);
self.setData({
//imgUrl: res.result.fileID
imgUrl: bufferImg
});
wx.hideLoading();
},
fail: err => {
console.error('云函数调用失败', err)
}
})
}
})
可以获得一个返回值,里面有个图片的buffer,转化buffer即可展示图片内容。
3、转化buffer流成图片的三种方法
3.1 直接将buffer转化Base64
console.log('云函数调用成功返回值:', res);
let bufferImg = "data:image/png;base64," + wx.arrayBufferToBase64(res.result.buffer);
self.setData({
imgUrl: bufferImg
});
这里用到的方法是 wx.arrayBufferToBase64(buffer)转化,加好base64头,即可食用~
- 优点: 方便简单
- 确定: 阅后即焚,无法保存,个别场景可能需要缓存或者拼接canvas海报
3.2 在云函数直接将Buffer上传到云存储
await cloud.uploadFile({
cloudPath: 'test/' + event.userInfo.openId + '.jpg', //这里如果可以重复就用openId,如果不可能重复就用
fileContent: result.buffer, //处理buffer 二进制数据
success: res => {
// 文件地址
console.log(res.fileID)
},
fail: err =>{
console.log(err)
}
})
将生成的小程序码上传到自带的云存储上,可以长期永久保存
- 优点: 长期保存,合适只要生成一次反复使用的场景
- 缺点: 生成量大的话,比较占用有限云存储资源
3.3 将图片转化保存在手机本地
let { buffer } = res.result;
const wxFile = wx.getFileSystemManager();
const filePath = wx.env.USER_DATA_PATH + '/test.jpg';
//把图片写在本地
wxFile.writeFile({
filePath,
encoding: "binary",
data: buffer,
success: res => {
console.log(res); //writeFile:ok
self.setData({
imgUrl: filePath
});
}
})
这里用到的是wx.getFileSystemManager()的方法,将图片buffer转化后保存一个本地地址~
- 优点: 生成实体地址,有时候图片太大,base64会出现一些诡异的BUG
- 缺点: 耗时
4、最终方案
经过综合考虑,这里使用的是不限次数的 openapi.wxacode.getUnlimited方法。
云函数部分:
const cloud = require('wx-server-sdk')
cloud.init()
exports.main = async (event, context) => {
try {
const result = await cloud.openapi.wxacode.getUnlimited({
scene: event.scene
});
console.log(result)
return await cloud.uploadFile({
cloudPath: 'test/' + event.userInfo.openId + '.jpg',
fileContent: result.buffer, //处理buffer 二进制数据
success: res => {
// 文件地址
console.log(res.fileID)
},
fail: console.error
})
} catch (err) {
console.log(err)
return err
}
}
页面代码:
Page({
data: {
imgUrl: "" //图片地址
},
getWxacode() {
wx.cloud.init();
let self = this;
wx.showLoading({
title: '请求云函数'
})
// 调用云函数 获取 内容
wx.cloud.callFunction({
name: 'getWxacode',
data: {
scene: "goTo:pages/home/index"
},
success: res => {
console.log('云函数调用成功', res);
self.setData({
imgUrl: res.result.fileID
});
wx.hideLoading();
},
fail: err => {
console.error('云函数调用失败', err)
}
})
},
})
5、注意事项
5.1 生成码一共有三种方法:
- openapi.wxacode.get 小程序码,可以直接生成path,但不能传参,有次数限制
- openapi.wxacode.createQRCode 二维码,有次数限制
- openapi.wxacode.getUnlimited 特定scene传参,无次数限制 (推荐使用)
1和2方法累积10w次限制
5.2 代码报错,跑不了等
记得初始化 wx.cloud.init();
记得部署云函数~ ctrl+s 是没用的~~~
记得先本地调试好,再上传~~~
官方文档地址:
https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/qr-code/wxacode.get.html
大佬威武
楼主有没试过 isHyaline 这个参数?生成不了透明的小程序码
主要是忍不住想评论下那句 “前端一条龙不求人(后端)”,NB
学习了
收藏了
第三种方法writefile的时候 总报错{errMsg: "writeFile:fail atob is not defined"}怎么办啊
请教下,通过转base64直接显示到image组件后,如何再调用saveImageToPhotosAlbum下载图片?也就是如何拿到这张图的临时文件地址?或者有其他实现思路呢?