uni.downloadFile返回的tempFilePath是仅当前会话有效的临时文件路径(如uni-file://xxx.jpg),非永久路径,不可直接用于src或a.href,离开success回调即失效。

uni.downloadFile 是唯一能直接通过 URL 下载网络图片的最新 API,但它不等于“保存到相册”或“触发浏览器下载”——它只负责把图片拉到本地临时路径,后续动作必须手动衔接。
uni.downloadFile 调用后,tempFilePath 是什么?
它是一个仅在当前会话有效的临时文件路径(如 uni-file://xxx.jpg),不是永久路径,也不能直接用于 src 或 a.href。不同平台表现差异大:
- 微信小程序:可直接传给
uni.sa veImageToPhotosAlbum保存到相册 - App 端(iOS/Android):同样支持
uni.sa veImageToPhotosAlbum,但 Android 需提前申请WRITE_EXTERNAL_STORAGE权限,iOS 需检查相册授权状态 - H5 端:
tempFilePath无效,无法使用,必须换方案(见下一条)
H5 端不能用 uni.downloadFile 下载图片?
对,uni.downloadFile 在 H5 上实际调用的是 XMLHttpRequest,返回的 tempFilePath 是伪造值(如 https://fake/xxx),无法读取或展示。此时必须绕过 uni API,用原生方式处理:
- 跨域图片:加
crossOrigin="anonymous"后 draw 到 canvas,再用canvas.toDataURL()转 base64,最后用触发下载 - 同源图片:可直接用
fetch+blob+URL.createObjectURL()生成可下载链接 - 注意:微信内置浏览器(H5)不支持自动下载,只能提示用户「长按图片保存」
为什么下载后图片打不开或报错「文件不存在」?
常见原因不是代码写错,而是路径或时机问题:
res.tempFilePath只在success回调里有效,离开回调就失效 —— 别把它存到 data 里异步用- 部分安卓机型对文件名含特殊字符(如中文、空格、#)敏感,建议用
encodeURIComponent处理原始 URL 后截取后缀,或统一用.png - 微信小程序中,如果图片是 HTTPS 但证书不合规,
statusCode可能为 0,res.tempFilePath为空,需在success里加if (!res.tempFilePath)判断 - App 端 debug 模式下临时路径可查,但真机打包后路径不可见,别依赖日志打印路径去调试
真正棘手的,往往不是“图片怎么下到本地”,而是下载完成之后文件落在什么位置、该怎么调用、用户到底看不看得到,以及权限是否在中途被拦住。说到底,跨端图片下载其实对应着三套完全不同的处理逻辑:小程序端走 sa veImageToPhotosAlbum,App 端要把权限校验补齐,H5 端则应彻底放弃 uni.downloadFile,转而使用 canvas/fetch。只要其中任何一环漏掉,用户点下去,大概率就是一次无提示的静默失败。
