应使用uni.chooseimage并按场景设置sourcetype:头像点击设['album'],长按设['camera'];注意h5不支持相机直拍,app和小程序需配置对应权限,上传前须校验大小并压缩。

uni-app里怎么触发相机或相册选图
直接调用 uni.chooseImage 会同时弹出相机和相册选项,但很多场景需要明确区分——比如点击头像时默认走相册,长按才唤起相机。注意:H5 端不支持相机直拍,sourceType 设为 ['camera'] 在 H5 上会被忽略,实际仍走文件选择;App 和小程序端才真正生效。
推荐写法:
uni.chooseImage({
sourceType: ['album', 'camera'], // 顺序影响 iOS 弹窗按钮排列
sizeType: ['compressed'], // 优先压缩图,避免大图上传失败
count: 1,
success: (res) => {
const tempFilePath = res.tempFiles[0].path;
// 后续赋值给头像变量、预览、上传等
}
});
常见错误:没传 count: 1,导致 iOS 多选后只取第一个却无提示;或者在 H5 上硬设 ['camera'],结果用户点不动、也不报错,体验断层。
头像替换后如何实时预览并上传
选图成功后,tempFilePath 是临时路径,可直接赋给 <image></image> 的 src 实现本地预览。但注意:tempFilePath 不能直接发给后端,必须用 uni.uploadFile 上传,或转成 base64(仅小图且非生产环境)。
关键点:
-
uni.uploadFile的filePath必须是tempFiles[0].path,不是tempFilePaths[0](旧版字段已弃用) - 上传前建议校验文件大小,比如限制 ≤2MB:
res.tempFiles[0].size - 安卓真机上,部分相册图片路径含空格或特殊字符,
uploadFile可能静默失败,建议用uni.getFileSystemManager().readFile兜底转 base64(仅小图)
不同平台对 camera 权限的处理差异
微信小程序需在 app.json 里声明 permission,否则 iOS 真机点相机无响应;App 端需在 manifest 中勾选相机权限;H5 则完全依赖浏览器策略,且 iOS Safari 不允许 JS 主动唤起相机(只能通过 <input type="file" capture="camera">,但 uni-app 封装层不暴露该能力)。
实操建议:
- 微信小程序:确认
mp-weixin/app.json含"permission": { "scope.userCamera": { "desc": "用于拍照上传头像" } } - App:HBuilderX → manifest → 模块权限配置 → 勾选「相机」和「相册」
- H5:降级为纯相册选择,或提示“请在手机浏览器中手动上传”
容易被忽略的是:iOS 微信内嵌页首次调用相机时,系统弹窗可能被遮挡或延迟,建议加个轻提示“请允许访问相机”,再延时 300ms 执行 chooseImage。
头像裁剪与压缩要不要做
不做裁剪,用户上传歪图、大背景图,后端存下来展示变形;不做压缩,4K 图片上传慢、失败率高、CDN 流量贵。uni-app 官方不内置裁剪,得靠插件或自己实现。
轻量方案:
- 用
uni-app-cropper插件(注意选支持 Vue3 的版本),它基于 canvas,兼容 App/H5/小程序 - 压缩用
uni.compressImage,但仅 App 和小程序支持;H5 需自己 canvas drawImage 缩放 - 更稳的做法:上传原图,后端返回裁剪后 URL(带参数如
?x=100&y=100&w=200&h=200),前端直接渲染 CDN 裁剪地址
真实项目里,90% 的头像问题出在“以为前端传了图就行”,结果用户上传一张 8MB 的 iPhone 实况图,上传卡死、接口超时、后台 OOM——压缩和尺寸校验,一个都不能少。











