背景
我们项目要添加一个拍照功能,h5端通过将canvas数据导出blob url再模拟点击a链接就可以实现。但是小程序不能打开webview下生成的blob url,并且JSSDK previewImage 也只能预览网络链接,postMessage 需要关闭webview才能处理。
实现
传递数据:
navigateTo 可以导航到小程序页面并携带参数,将canvas导出base64再作为参数传递。
性能问题:
setData 数据过大导致微信崩掉
- 将拿到的数据存到
本地用户文件,setData 使用本地路径,否则微信容易崩溃。 - 导出时使用jpeg编码。
- 使用压缩。
代码
webview:
const base64Body = (base64 as string).replace(/data:image\/(\w+);base64,/, '');
wx.miniProgram.navigateTo({
url: `/preview/preview?data=${encodeURIComponent(base64Body)}`
})
注意:由于使用url传递,所以需要使用 encodeURIComponent 编码一下,相应的,小程序页面收到后需要解码。
小程序页面:
onLoad: function(params) {
const data = decodeURIComponent(params.data);
const buffer = wx.base64ToArrayBuffer(data);
const filePath = `${wx.env.USER_DATA_PATH}/photo/${Date.now()}.jpg`;
fs.writeFile({
data: buffer,
encoding: 'binary',
filePath: filePath,
success: res => {
wx.previewImage({
current: filePath,
urls: [filePath]
});
},
fail: res => {
console.log('ERROR_BASE64SRC_WRITE', res);
},
});
}
- 文件最好放统一路径,因为这会占用
本地用户文件的那10M空间,需要在你使用完或打开小程序时清理该目录的文件。 - 如需启用压缩,可引入压缩库在webview中压缩arraybuffer后再转base64,然后使用微信的 FileSystemManager.unzip 解压。这里图片导出的jpg压缩意义不大。
结束
经测试这种方式传输两三兆的文件微信没有 教我做事,10+M的文件没有出现崩溃,但是开发者工具提示 数据传输长度为 12316 KB,存在有性能问题!。