uni-app 多附件上传需分类型处理:chooseimage 选图片并直接预览,choosemessagefile 选非图片文件但 ios 路径仅临时有效;须立即转为统一结构并串行/并行上传,非图片文件仅能图标+名称展示,pdf用uni.opendocument预览,视频需单独choosevideo。

uni-app 里 chooseMessageFile 和 chooseImage 怎么选
多附件上传预览,核心是先拿到文件对象列表 —— 但 uni-app 没有统一的「多类型多文件选择」API,得按类型拆开处理。chooseImage 只能选图片,chooseMessageFile(iOS/Android 10+ 支持)才能选任意文件(含 PDF、Excel、视频等),且后者不支持直接预览非图片类型。
-
chooseImage返回的是tempFiles数组,每个 item 有path、size、name,可直接用<image></image>标签预览 -
chooseMessageFile返回的tempFiles中,path在 Android 上是真实路径(可读),iOS 上是沙盒临时路径(仅能通过uni.getFileInfo或上传接口读取,不能直接src渲染) - 想统一管理图片 + 其他文件,得分开调用,再合并数据结构;别指望一个 API 搞定所有类型
怎么把选中的文件存成可渲染/可上传的列表
用户选完后,不能直接把原始 tempFiles 存进 data —— 它们生命周期短、路径不稳定,尤其 iOS 的 chooseMessageFile 路径几秒后就失效。必须立刻转成可用形式。
- 图片类:用
uni.compressImage(可选)或直接保留tempFiles[i].path,赋值给fileList中的url字段,供<image></image>渲染 - 非图片类:需立即调用
uni.getFileInfo({ filePath })获取size和校验,同时生成唯一id和人工name(tempFiles[i].name在某些安卓机型上为空) - 列表项建议结构:
{ id: 'xxx', url: 'xxx', name: 'xxx', size: 12345, type: 'image/jpeg' || 'application/pdf', path: 'xxx' },其中url仅图片有值,其他用占位图标 + 文件名显示
上传时 uni.uploadFile 怎么传多个文件
uni-app 的 uni.uploadFile 不支持一次传多个文件,所谓「多附件上传」本质是串行或并行多次调用。并发太多容易被拦截或失败,得控制节奏。
- 别用 for 循环直接发 —— 缺少错误隔离,一个失败全崩;改用
Promise.allSettled包裹每个uni.uploadFile调用 - 每个请求的
filePath必须是当时选中后保存的path,不能用旧的或已清空的临时路径;iOS 上若用chooseMessageFile后没立刻上传,大概率报错fail file not exist - 后端字段名要对齐:如果后端要求每个文件用
file[0]、file[1],前端就得每次传不同name;若统一用file,则后端需支持数组解析
预览 PDF / 视频这类非图片文件怎么办
uni-app 内置组件不支持直接渲染 PDF 或视频缩略图,也没法像 Web 那样用 <embed></embed> 或 <video></video> 标签加载本地路径(iOS 尤其严格)。
- PDF:只能跳转内置 WebView 预览,用
uni.openDocument({ filePath: xxx }),注意它会新开页面,且 Android 需提前授权存储权限 - 视频:无法预览缩略图,但可调用
uni.chooseVideo单独选,它返回的tempFilePath才能用于<video></video>播放;混在chooseMessageFile里选的视频,iOS 上基本不可播 - 通用方案:非图片文件统一显示为「?
fileName」文字 + 文件图标,点击后根据类型分别处理(PDF 调openDocument,视频提示「请单独上传」)
真正麻烦的不是代码怎么写,而是不同平台对「文件路径」的处置逻辑完全不一致 —— iOS 的临时路径、安卓的 scoped storage、微信小程序的独立沙盒,都得各自兜底。别省那两行兼容判断,否则上线后用户点不动附件,第一反应永远是「功能坏了」,而不是「系统限制」。











