file-extname 是最直接有效的格式限制方式,配合 file-mediatype="image" 可在选择阶段过滤不支持格式,但需注意其仅匹配扩展名、ios 相册可能仍返回 webp、且必须结合 type 校验与转码处理。

uni-file-picker 的 file-extname 是最直接有效的限制方式
直接用 uni-file-picker 组件,配合 file-extname="png,jpg,jpeg" 就能从系统相册/文件管理器里过滤掉 tif、webp、bmp 等不支持的格式——这是目前唯一能在选择阶段就真正拦截的方案。
注意三点:
-
file-extname只匹配文件扩展名(如xxx.png),不校验 MIME 类型或二进制头,所以用户重命名evil.exe为test.jpg仍能过;但对正常用户已足够可靠 - 必须和
file-mediatype="image"一起用,否则file-extname在非图片场景下可能无效 - 微信小程序真机上,
file-extname对安卓相册生效,但 iOS 相册仍可能返回 webp(尤其微信聊天图)——这不是组件问题,是系统行为
uni.chooseImage 无法靠参数限制格式,只能事后校验
uni.chooseImage 的 sourceType 和 sizeType 只控制来源(相册/相机)和压缩质量,**完全不支持后缀过滤**。选完 tif 或 webp,API 会静默返回临时路径,不会报错也不会拦截。
必须手动检查:
- 取
tempFiles[0].path,用正则/\.jpg$|\.jpeg$|\.png$/i匹配后缀 - 更稳妥的做法是同时读
tempFiles[0].name,因为部分安卓机返回的path不含扩展名,但name总是有 - 校验失败后,必须显式调用
uni.showToast({ title: '仅支持 JPG/PNG 格式', icon: 'none' }),否则用户无感知
webp 格式在小程序里是个隐藏雷区
很多安卓手机(尤其华为、小米)从相册选图默认返回 webp,而你的后端若只接受 image/jpeg 或 image/png,上传会 415 或静默失败,前端预览也为空白——控制台甚至不报错。
应对策略:
- 不要依赖后缀判断:webp 文件可能被系统返回为
.jpg后缀,但实际是 webp 编码 - 关键检测点是
tempFiles[0].type,iOS 和部分安卓会返回image/webp - 如果后端不支持 webp,必须用
uni.compressImage(仅 H5/APP)或 canvas(小程序)转成 jpg/png,不能直接传原图
limit="1" 不等于“禁止重复选择”
:limit="1" 只限制单次最多选 1 张,**不限制用户点第二次**。第二次选图会覆盖第一次的 v-model 值,但 UI 没任何反馈,用户以为没响应。
真实可用的防重复方案:
- 加个禁用态按钮:
<button :disabled="imageValue.length > 0">上传头像</button> - 在
@select回调里清空 input(如果用了原生<input type="file">) - 更彻底的是监听
@select后立即this.$refs.picker.clear()(需组件支持 clear 方法)
webp 和重复选择这两处,最容易在线上被用户反复触发却查不出原因。











