uni.saveimagetophotosalbum不接受base64,必须先转为本地filepath:先去除data:image/xxx;base64,前缀,再用uni.base64toarraybuffer转arraybuffer,最后以encoding:'binary'写入wx.env.user_data_path路径并调用api。

uni.saveImageToPhotosAlbum不接受Base64,必须先转filePath
直接传data:image/png;base64,xxx给uni.saveImageToPhotosAlbum会静默失败,API只认本地文件路径。核心动作不是“存Base64”,而是“把Base64写成一个真实可读的filePath”。关键三步:去前缀 → 转ArrayBuffer → 写入wx.env.USER_DATA_PATH。
-
base64.replace(/^data:image\/\w+;base64,/, '')必须执行,否则uni.base64ToArrayBuffer会解码错乱 - 必须用
uni.base64ToArrayBuffer(base64)得到ArrayBuffer,不能传原始字符串 -
encoding: 'binary'是硬性要求,和ArrayBuffer配对才稳定;设'base64'仅适用于字符串+base64编码组合,但该组合在iOS/部分安卓真机上常出黑图 -
filePath必须以${wx.env.USER_DATA_PATH}/xxx.png格式构造,_doc/、temp/、/data/等路径在小程序沙箱中无权限 - 文件名建议带时间戳或随机串,如
img_${Date.now()}.png,避免重复写入失败
权限检查不能只调一次uni.authorize
用户首次拒绝授权后,再次调用uni.authorize会直接进fail回调,不会弹窗。必须先查scope.writePhotosAlbum状态,再决定走授权还是跳设置页。
- 用
uni.getSetting获取当前权限状态 - 若
res.authSetting['scope.writePhotosAlbum'] === false:用户已明确拒绝,应立即调uni.openSetting - 若
=== undefined:才是首次,可用uni.authorize -
uni.saveImageToPhotosAlbum的fail回调里,检查err.errMsg是否含authorize字样,区分权限失败和其他错误(如路径非法、文件损坏)
大图保存前要清理USER_DATA_PATH空间
微信小程序单文件写入上限约10MB,但wx.env.USER_DATA_PATH总空间有限。反复保存海报类大图(>2MB)后,writeFile可能静默失败,且无明确报错。
- 每次保存前,用
uni.getFileSystemManager().getSavedFileList()查已有文件 - 按时间或大小筛选旧文件,用
uni.getFileSystemManager().removeSavedFile()清理 - 尤其注意:
getSavedFileList返回的是已通过saveFile保存的文件,不包含writeFile写入的临时文件——所以清理目标应是自己写入后又调过saveImageToPhotosAlbum的那些
别用过滤器处理Base64图片
过滤器(filters)是同步纯函数,无法做MIME补全、空格清理、异步校验等必要操作。强行塞进过滤器会导致ERR_INVALID_URL(H5)、image空白(小程序)、canvas跨域失败(H5)等问题。
- Base64本身就是合法
data:URI,不需要“转成路径”;src="data:image/png;base64,xxx"可直接用 - 标准化处理(补前缀、
encodeURIComponent、统一MIME为image/png)应在data或computed中完成 - 后端若只返回纯Base64字符串(无
data:image/xxx;base64,),必须手动补,不能依赖过滤器自动识别
encoding: 'base64' + 字符串写入极其敏感,哪怕Base64末尾多一个换行或空格,就黑图。所以base64ToArrayBuffer + encoding: 'binary'不是“可选优化”,而是跨端保底方案。











