uni.downloadFile在App和小程序端支持task.onProgressUpdate监听进度,H5端不支持且progress恒为0;需立即绑定监听、节流更新UI,并注意临时路径需持久化后才能打开或保存。

uni.downloadFile 下载文件时如何监听进度
uni.downloadFile 本身不支持直接传入 onProgressUpdate 回调,必须用 uni.downloadFile + uni.showLoading + 定时轮询临时文件路径的方式模拟进度——但这是错的。实际可用的是 uni.downloadFile 返回的 task 对象,它在 App 和小程序平台均支持 onProgressUpdate 方法。
常见错误是直接在 success 回调里读取文件,导致无法感知下载中状态;或误以为 H5 平台也支持进度监听(其实不支持)。
- App(iOS/Android)和微信/支付宝/字节小程序:支持
task.onProgressUpdate - H5 平台:
uni.downloadFile底层走fetch或XMLHttpRequest,但 uni-app 没暴露原生事件,进度始终为 0 或 undefined - 必须在调用
uni.downloadFile后立刻对返回的task绑定监听,不能延迟
进度条 UI 如何与 task.onProgressUpdate 同步更新
Vue 响应式数据更新需注意触发时机:不能在 onProgressUpdate 中直接赋值 this.progress = e.progress(H5 下 e.progress 可能恒为 0),且小程序 setData 频率过高会卡顿,建议加节流。
示例关键代码:
const task = uni.downloadFile({
url: 'https://example.com/file.pdf',
success: (res) => {
if (res.statusCode === 200) {
this.tempFilePath = res.tempFilePath;
}
}
});
task.onProgressUpdate((e) => {
// e.progress 是 0~100 的整数,仅 App 和小程序有效
if (e.progress > 0) {
this.progress = e.progress;
}
});
- 进度条组件推荐用
<progress :percent="progress"></progress>,不要用自定义 canvas 动画,避免兼容问题 - App 平台可能触发多次 100%,需在 success 后手动设
this.progress = 100并清空 task 引用 - 务必在页面 onUnload 里调用
task.abort(),防止页面销毁后还在后台下载
下载完成后的文件如何保存到本地相册或打开预览
下载得到的是临时路径 res.tempFilePath,不能直接用于 uni.openDocument 或 uni.saveImageToPhotosAlbum,需先用 uni.getFileInfo 校验,再根据平台选择处理方式。
- PDF/Office 文件:用
uni.openDocument({ filePath: res.tempFilePath }),注意 iOS 需提前在manifest.json配置NSAppleMusicUsageDescription等权限(实际不影响,但部分版本报 warning) - 图片:H5 用
location.href = res.tempFilePath触发浏览器下载;小程序调uni.saveImageToPhotosAlbum;App 调uni.saveFile再用uni.openDocument打开 - 安卓真机上
res.tempFilePath可能带 file:// 前缀,uni.openDocument会失败,需用res.tempFilePath.replace('file://', '')清洗
为什么 H5 下进度条永远不动
因为 H5 平台的 uni.downloadFile 是基于 fetch 封装,而 fetch 不提供上传/下载进度事件;uni-app 未做 polyfill,e.progress 始终为 0。
如果必须在 H5 显示近似进度,只能退化方案:
- 用
uni.showLoading({ title: '下载中...' })+uni.hideLoading()做状态提示 - 服务端配合返回 Content-Length,前端用
XMLHttpRequest手动发起请求并监听onprogress,但会绕过 uni-app 的统一拦截和登录态管理 - 放弃 H5 进度条,统一文案提示“文件较大,请稍候”,避免用户误判失败
真正跨平台稳定的方案,是接受 H5 无进度、其他平台有进度的事实,而不是强行统一逻辑——这点容易被忽略,但省去大量兼容 hack。











