uni.chooseImage 在真机(尤其 iOS)返回临时路径而非 base64,不能直接绑定 image src;多图需分别 uploadFile,预览/上传/状态须分三类数据管理,注意平台差异与并发控制。

uni-app 里 uni.chooseImage 怎么用才不踩坑
直接说结论:别只看文档示例,uni.chooseImage 在真机(尤其 iOS)上默认返回的是临时文件路径,不是 base64,也不能直接当 src 绑定给 <image>——除非你手动转成本地临时路径或使用 uni.uploadFile 后的服务器 URL。
常见错误现象:chooseImage 返回的 tempFilePaths 在 H5 正常显示,但在微信小程序或 App 端白屏;或者上传后服务端接收不到文件(传了路径字符串而非二进制流)。
-
count参数在不同平台限制不同:微信小程序最多 9 张,App 端默认是 9,H5 实际取决于浏览器 input[type=file] 的 multiple 行为 - 务必检查
sourceType:设为['album', 'camera']才支持相册+拍照;只写['camera']在某些安卓机型会报错“未授权相机”但不提示 - 真机调试时,iOS 对
tempFilePaths的生命周期极短,不能缓存字符串反复用,必须立刻上传或调用uni.saveFile持久化(一般不必要)
多图上传前怎么统一处理预览和状态管理
预览不是把 tempFilePaths 直接塞进数组就完事。你需要同步维护三类数据:原始临时路径(用于上传)、本地可渲染 URL(用于 <image> 的 src)、上传状态(pending / success / fail)。
关键点在于:H5 下 tempFilePaths 是 blob URL,可直接渲染;小程序和 App 下必须用 uni.getImageInfo 或直接赋值(小程序支持直接用临时路径),但要注意路径合法性。
- 推荐结构:
images: [{ tempPath: '', url: '', status: 'ready' }],每次chooseImage后用map构造新数组,避免响应式失效 - 预览点击事件别直接传
item.tempPath给uni.previewImage——它要求是数组,且需确保所有路径都有效;应传this.images.map(i => i.url) - 删除某张图时,记得同时从
tempFiles缓存中清除对应项,否则重复选择可能触发“已选上限”误判
uni.uploadFile 上传多图为什么总卡在 pending 或 400
根本原因:没理解它是单文件上传接口,不是批量。所谓“多图上传”,本质是串行或并行多次调用 uni.uploadFile,每次传一张图的 tempFilePath。
典型错误:把整个 tempFilePaths 数组当作一个文件路径传进去,导致后端收不到 file 字段;或者没设置正确的 name(后端接收字段名),例如后端要 images[],你却固定写 name: 'file'。
- 并发控制很重要:微信小程序限制最多 10 个 concurrent upload,App 端也建议限制在 3–5 个并发,用
Promise.allSettled+ 分批处理更稳 -
formData里不要传复杂对象,只传字符串键值对;如需传图片序号,用{ index: '0' },别传{ index: 0 }(部分安卓机型会丢类型) - 上传成功后,服务端返回的 URL 建议立刻替换到对应
images[i].url,而不是等全部传完再统一赋值——用户需要实时反馈
真机调试时图片旋转、压缩、宽高异常怎么处理
不是 bug,是原生层行为:iOS 拍照图自带 EXIF 旋转信息,uni.chooseImage 返回的临时路径在渲染时会被自动纠正,但上传后服务端拿到的是未旋转原始图;安卓部分厂商相册图可能被系统压缩过,size 和实际分辨率对不上。
如果你的业务强依赖尺寸或方向(比如证件照上传),不能跳过这步:
- 用
uni.getImageInfo拿到真实width/height和orientation,判断是否需要前端 canvas 旋转(仅 H5 可靠,小程序 canvas 旋转兼容性差) - 压缩建议交给后端做,前端用
uni.compressImage风险高:它不返回压缩后尺寸,且在低内存安卓机上容易失败静默 - 上传前校验尺寸,比如要求最小宽度 800,可用
getImageInfo后比对,不达标就uni.showToast({ title: '图片太小', icon: 'none' })并跳过上传
最易被忽略的一点:微信小程序开发工具里图片正常,真机上却黑屏或拉伸——大概率是 <image> 的 mode 属性没设对,默认 scaleToFill 会变形,改成 aspectFit 更安全。


















