应改用 uni.chooseMedia 并显式设置 mediaType: ['image'],注意返回结构为 tempFiles 数组,区分 cancel 与 auth deny 错误,H5 跳过压缩,Android 加延时防文件未就绪。

uni.chooseImage 在 iOS 和 Android 上行为不一致怎么办
uni.chooseImage 的实际表现和文档描述有出入,尤其在 iOS 上可能直接跳转相机、不弹相册选择框,Android 则相对稳定。这不是 bug,而是平台原生限制导致的默认行为差异。
关键点在于:iOS 系统不允许 H5 或 WebView 层直接唤起「纯相册选择」界面,uni-app 会退化为先调用相机;而 Android 可以正常弹出系统相册选择器。
- 必须显式设置
sourceType为['album'],否则 iOS 默认走['camera', 'album'],且优先触发相机 - 如果只想选相册,不要传空数组或省略该参数,否则各端行为更不可控
- 真机调试时,iOS 模拟器无法测试相册功能,必须用真机 + 开启相册权限(
NSPhotoLibraryUsageDescription) - uni-app 3.0+ 推荐改用
uni.chooseMedia,它对图片/视频、多选、压缩控制更统一,且 iOS 下能真正弹出相册选择页
uni.chooseMedia 替代 uni.chooseImage 后怎么兼容老写法
uni.chooseMedia 是 uni-app 官方推荐的新 API,支持多图、视频、压缩、裁剪提示等,但返回结构和旧 API 不同,直接替换会报错。
最常踩的坑是:把 tempFilePaths 当成数组直接遍历,其实新 API 返回的是 tempFiles 数组,每个元素含 fileType、tempFilePath、size 等字段。
- 老代码:
res.tempFilePaths[0]→ 新代码应改为res.tempFiles[0].tempFilePath - 要限制只选图片,必须加
mediaType: ['image'],否则 iOS 可能默认允许选视频 - 需要压缩时,
compressionQuality仅在 App 端生效(iOS/Android),H5 不支持,别指望它在浏览器里起作用 - H5 端仍走 input[type=file],所以样式和交互完全不可控,不能假设它会弹系统相册 —— 实际就是个文件上传按钮
用户点了取消或拒绝授权后怎么判断并友好提示
很多开发者只处理成功回调,忽略失败场景,结果用户点了「不允许访问相册」后界面卡住或报错,体验极差。
uni-app 的 API 失败回调中,errCode 和 errMsg 是唯一可靠依据,不能只靠 try/catch 或判断 res 是否为空。
- iOS 拒绝相册权限时,
errMsg通常是"chooseImage:fail auth deny"或"chooseMedia:fail auth deny" - 用户手动点击取消,
errMsg多为"chooseImage:fail cancel",注意大小写和空格 - Android 6.0+ 动态权限被拒后,再次调用会直接进 fail 回调,不会二次弹窗,需引导用户去设置页手动开启
- 建议统一拦截
fail回调,用if (err.errMsg.includes('cancel'))区分取消和错误,避免把用户主动取消当成异常上报
选完图片后预览、压缩、上传三步连做容易漏哪环
从选择到上传不是线性流程,中间每一步都可能失败或被中断,尤其是压缩环节经常被忽略兼容性问题。
常见断点:H5 端 uni.compressImage 不支持,调用即报错;App 端压缩后路径是临时的,必须在本次生命周期内完成上传,否则下次启动就失效。
- 压缩前务必检查平台:
uni.getSystemInfoSync().platform !== 'h5',H5 直接跳过压缩或用 canvas 自行实现 -
uni.uploadFile的filePath必须是tempFilePath或tempFiles[x].tempFilePath,不能传原始相册路径(iOS 根本拿不到) - 多图上传别用 for 循环直接发请求,容易触发并发限制或 token 过期,建议用 Promise.all + 错误隔离,单张失败不影响其余
- Android 部分机型(如华为 EMUI)对
tempFilePath读取有延迟,压缩后立即上传可能报 “file not found”,加个setTimeout100ms 再传更稳
最麻烦的其实是 iOS 的沙盒路径和权限链:选图 → 生成 temp 路径 → 压缩 → 上传 → 服务端解析。任意一环路径格式不对或 MIME 类型缺失,后端就解析失败。别信“选了就能传”,得每一步都打日志验证。


















