uni.downloadFile 下载失败或 tempFilePath 为空,主因是后端响应状态码非200或 Content-Type 不合规;需校验 statusCode、设置正确响应头、下载后立即保存或持久化,并按平台差异处理权限、路径、后缀及兼容性。
uni.downloadFile 下载失败或 tempFilePath 为空?先看状态码和网络响应头
很多视频“点保存没反应”,根本不是代码写错了,而是 uni.downloadfile 拿不到有效文件路径——常见原因是后端返回的响应头不合规,或者 http 状态码不是 200。
微信小程序尤其敏感:如果服务端返回的 Content-Type 不是 video/mp4(或对应格式),哪怕文件内容完全正确,res.tempFilePath 也可能为空或下载中断。
- 务必在
success回调里加判断:if (res.statusCode !== 200),别只依赖res.tempFilePath是否存在 - 后端需明确设置响应头:
Content-Type: video/mp4;iOS 还要求有Content-Disposition: inline(非必须但更稳) - H5 端不走原生相册 API,
uni.saveVideoToPhotosAlbum会静默失败,需用a[href][download]或 Blob URL 方式另做降级
uni.saveVideoToPhotosAlbum 报 “fail no permission”?权限不是“申请一次就永久有效”
iOS 和 Android 都不会在首次授权后一直放行——用户手动关闭过相册权限、系统升级、甚至 App 重装后,scope.writePhotosAlbum 都可能变回未授权状态。直接调用保存必然失败。
- 必须在调用前主动检测:
uni.getSetting({ withSubscriptions: true }),检查authSetting['scope.writePhotosAlbum'] - 未授权时,不能直接跳
saveVideoToPhotosAlbum,得先uni.authorize({ scope: 'scope.writePhotosAlbum' }),且要处理authorize的fail(比如用户点了“不允许”) - iOS 还需在
manifest.json → iOS → 权限配置中补全NSPhotoLibraryUsageDescription,否则弹窗都不出来,静默拒绝
小程序里保存 MP4 总是失败?注意文件来源和临时路径生命周期
微信小程序对 filePath 要求极严:必须是 uni.downloadFile 返回的 tempFilePath,且该路径 24 小时内有效;从 uni.uploadFile、uni.chooseVideo 或 WebView 传来的路径一律不认。
- 别尝试拼接本地路径(如
/wxfile/xxx.mp4)或用uni.getFileSystemManager()自己写入再读取——小程序环境不认这些 - 下载完成立刻保存,别缓存
tempFilePath后异步调用;若需延时,先用uni.saveFile持久化,再用savedFilePath传给saveVideoToPhotosAlbum - 某些 CDN 或防盗链地址会返回 302 重定向,而微信基础库旧版本(如 2.25.0 以下)不自动跟随,导致下载空文件——加
header: { 'User-Agent': 'WXMiniProgram' }有时能绕过
App 端(iOS/Android)保存成功却找不到视频?检查文件后缀和媒体库索引
Android 和 iOS 均依赖文件扩展名识别媒体类型。如果后端返回的是无后缀的二进制流(如 URL 是 /api/video?id=123),即使内容是 MP4,uni.saveVideoToPhotosAlbum 可能保存成功但相册不显示。
- 下载时手动补后缀:
const tempFilePath = res.tempFilePath + '.mp4'(仅限 App 端,小程序不支持改路径) - iOS 保存后需触发媒体库刷新(部分机型需要),可加个空
setTimeout再提示,或用plus.gallery.refresh()(5+ SDK) - Android 10+ 强制使用分区存储,
tempFilePath若落在CacheDir,保存到相册后系统可能延迟索引——建议下载时指定dir为Documents目录
最麻烦的其实是鸿蒙和快应用这类平台,它们根本不支持 saveVideoToPhotosAlbum,得用 UTS 插件调原生 API。真要全端兼容,得按平台分条件编译,不能指望一个函数打天下。










