uniCloud.uploadFile支持跨端上传但参数不统一:H5需用file(Blob/File)+cloudPath,小程序/App用tempFilePath作filePath;不支持多文件批量上传,须循环或Promise.all调用;上传成功后通过getTempFileURL获取可访问链接。

直接用 uniCloud.uploadFile 就能上传,但不同端(H5 / 小程序 / App)传参方式不一致,且云函数不能自动接收多文件——这是绝大多数人卡住的第一关。
uni-app 各端怎么获取合法的 filePath
上传前必须拿到平台认可的本地路径,不是随便一个 URL 或 Blob 都行:
- H5 端:
uni.chooseFile返回的tempFiles[0].path是 blob URL,不能直接传;必须先用FileReader转成 base64 或用fetch+ArrayBuffer构造可上传对象,再通过uniCloud.uploadFile的file参数传入(注意不是filePath) - 微信小程序:
uni.chooseImage或uni.chooseMessageFile返回的tempFiles[0].path可直接作为filePath使用 - App 端(iOS/Android):
uni.chooseFile返回的tempFiles[0].path也合法,但需确保是「临时路径」而非沙盒内持久路径(否则安卓可能报错uploadFile:fail file not found) - 注意:
filePath必须是本地临时路径,不能是网络地址、data:协议或uni-file-picker绑定的v-model值(那是云存储返回的fileID或url)
uniCloud.uploadFile 的参数陷阱
这个 API 看似简单,但三个关键参数稍不注意就失败:
-
filePath:只在小程序/App端有效;H5必须改用file(类型为Blob或File实例) -
cloudPath:必须带后缀(如"images/abc.jpg"),否则云存储无法识别 MIME 类型,返回的url可能打不开图片 -
name参数无效:uniCloud 的uploadFile不走传统 form 表单字段名逻辑,它不依赖name,所以别传;传了也不会报错,但纯属冗余 - 大文件(>5MB)在 H5 端容易触发浏览器内存溢出,建议前端先压缩或分片;小程序端限制由平台决定(微信约 50MB)
为什么不能一次传多个文件?
因为 uniCloud.uploadFile 接口设计就是单文件原子操作——它底层调用的是云服务商(阿里云 OSS / 腾讯云 COS)的单对象上传接口,不支持 multipart 批量解析。
- 常见错误:
TypeError: Cannot read property 'length' of undefined,本质是前端把多个File对象塞进一个请求,云函数收不到event.files(它压根不解析 multipart) - 正确做法:前端用
Promise.all并发调用多次uniCloud.uploadFile,每个请求只传一个文件 - 别试图在云函数里手动解析
event.body来“支持多文件”:腾讯云函数默认不支持multipart/form-data解析,阿里云虽可用busboy,但会显著增加冷启动时间与出错概率 - 如果真要打包上传(比如压缩包),得走
uni.uploadFile(非 uniCloud 版)上传到自建服务端,再由服务端解包并逐个调用uniCloud.uploadFile
上传后怎么拿到可访问的链接?
上传成功返回的 res.fileID 是唯一标识,但它是内部 ID,不能直接当 URL 用:
- 需要拼接成 CDN 地址:
https://<space-id>.cdn.bspapp.com/<res.fileid></res.fileid></space-id>(阿里云)或https://<space-id>.tcb.qcloud.la/<res.fileid></res.fileid></space-id>(腾讯云) - 更稳妥的方式是调用
uniCloud.getTempFileURL,传入fileID数组,它会返回带签名、可直接访问的临时 URL(有效期 2 小时) - 若需长期链接,应在云函数中调用
db.collection('files').add存储fileID和业务字段,并在需要时用getTempFileURL换取新链接 - 注意:
getTempFileURL不能在 H5 前端直接调用(会暴露权限),必须封装在云函数里,前端只调云函数
最易被忽略的一点:H5 端上传视频/大图时,uni.chooseFile 返回的 tempFiles[0].size 可能不准(尤其 iOS Safari),导致你误判是否超限;建议上传前用 new FileReader() 读取 File.size 再校验。


















