uni.uploadFile不支持直接传数组,必须手动循环调用:App/小程序端遍历tempFilePaths逐个上传,H5端需用File实例数组并设files字段;须控制并发、完善三回调、显式管理状态。
uni.uploadFile 不能直接传数组,必须手动循环调用
这是最常踩的坑:把 tempfilepaths 数组整个塞进 filepath 字段,结果报错 uploadfile:fail invalid file path。原因很简单——uni.uploadfile 是原生 api,只认单个路径(app/小程序)或 files 数组(h5),不解析对象、不支持数组展开。
真实做法分两步:
- 先调用
uni.chooseImage、uni.chooseMedia或uni.chooseMessageFile拿到tempFilePaths(App/小程序)或tempFiles(含路径和元信息) - H5 平台必须监听
的change事件,从event.target.files取File实例,再构造成files: [{ uri: file, name: 'file', fileName: file.name }] -
name字段建议统一设为'file'或后端约定的数组名(如'files[]'),避免后端收不到
并发数必须显式控制,3–5 是安全上限
微信小程序明确限制活跃 socket 连接 ≤10,iOS App 和部分安卓系统也有连接池硬限。盲目用 Promise.all 同时发起 10+ 个 uni.uploadFile,大概率触发超时、静默失败或 uploadFile:fail 无具体错误码。
推荐做法是轻量队列控制,并发数设为 3–5:
- 不用
Promise.all:一个失败整批 reject,无法定位哪个文件出问题,也不利于 UI 单独重试 - 可用
for...of + await串行(简单但慢),或引入p-limit类库(const limit = pLimit(4)) - 每个任务加唯一 ID(如
upload-${i}),方便和原始tempFilePaths[i]关联状态
H5 平台必须用 files 字段,filePath 完全无效
在 H5 环境下,filePath 参数被忽略,底层走的是 FormData 模拟上传。如果还沿用 App/小程序写法,会报 uploadFile:fail no file path——这不是 bug,是机制使然。
关键操作只有两个:
- 必须通过
获取FileList,不能用任何“路径字符串” - 调用
uni.uploadFile时删掉filePath,改用files: [{ uri: file, name: 'file', fileName: file.name }] -
fileName显式传,否则后端可能收到blob这类默认名,影响业务识别
必须写全 success/fail/complete 三回调
只写 success 是最大隐患。漏掉 fail 导致上传失败无提示;漏掉 complete 会导致 loading 状态卡死、用户重复点击提交按钮。
每个上传任务都该包裹 try/catch,单独记录状态:
-
fail回调里捕获错误并reject,避免静默失败 -
complete里统一做清理(如关闭全局 loading、释放内存引用) - 上传状态必须显式维护(如
status: 'uploading' | 'success' | 'failed'),不能只靠回调推断
实际并发逻辑复杂点在于平台行为不一致,H5 用 files、小程序用 filePath、App 两者都可能支持,但语义不同。最容易被忽略的是:没做平台判断就复用同一套上传参数,导致 H5 始终失败却以为是网络问题。











