capture属性仅为提示而非强制指令,其值应为"user"或"environment"而非已弃用的"camera",且必须配合accept="image/*"等明确媒体类型才能生效;加了capture仍弹相册是平台策略非bug,直连摄像头需改用getusermedia()。

capture 属性不是开关,而是提示
capture 本身不强制打开摄像头,它只是向浏览器“建议”:当用户点击这个 input[type="file"] 时,请优先调起对应硬件设备。是否响应、如何响应,完全取决于浏览器实现和系统策略。
常见错误现象包括:capture="camera" 在 iOS Safari 中被忽略、在新版 Chrome Android 中降级为默认行为、在桌面端基本无反应。根本原因在于:capture="camera" 不是 W3C 标准值,早已被弃用。
-
capture="user"和capture="environment"才是规范推荐写法,分别对应前置/后置摄像头 - 漏写
accept(比如只写capture="user"),capture就会失效 —— 浏览器需要明确的媒体类型语义才能决策硬件调用 -
accept="image/*"是触发拍照界面的前提;accept="video/*"才可能唤起录像;accept="audio/*"对应录音,此时capture="microphone"有效,user/environment被忽略
为什么加了 capture 还是弹相册?这不是 bug
iOS 和新版 Android 的设计逻辑一致:只要 accept="image/*" 存在,且设备支持拍照,系统级选择弹窗就会同时提供「拍照」和「从相册选取」两个入口。capture 并不能禁用相册选项 —— 这是平台层统一策略,不是浏览器 bug。
如果你真要绕过相册、直连摄像头,必须放弃 input[type="file"],改用 MediaDevices.getUserMedia() + canvas 捕获帧。但这带来新约束:
- 需显式请求 camera 权限,用户可拒绝
- 无法直接获取照片 EXIF(如方向、时间戳),需手动解析 ArrayBuffer
- 微信内嵌 WKWebView(iOS)对
getUserMedia支持不全,且部分版本要求 HTTPS
Android 和 iOS 行为差异必须 runtime 处理
iOS Safari 对 capture 更敏感:加上 capture="user" 就会禁用相册入口,用户无法退选;而老版 Android(如 4.x)不加 capture 就打不开相机,只能进图库。
推荐运行时 UA 检测并动态设置:
const input = document.querySelector('input[type="file"]');
if (/iPhone|iPad|iPod/.test(navigator.userAgent)) {
input.removeAttribute('capture');
} else {
input.setAttribute('capture', 'environment');
}
注意:capture 和 multiple 互斥 —— 加了 multiple 后,capture 会被忽略,系统只开放文件多选界面。
上传后必须处理 EXIF 方向问题
移动端拍的照片自带 Orientation 信息,但多数浏览器在 input[type="file"] 上传时不会自动旋转图像,导致横拍照片显示为竖向、竖拍变横向。
这不是 capture 的问题,但常被一起踩坑。解决方案是上传前用 FileReader + DataView 解析 EXIF 的 0x0112 tag,再用 canvas 绘制修正后的图像。
关键点:getOrientation(file, callback) 这类工具函数必须存在,否则用户拍完就传,后端或前端展示时图片方向全是错的 —— 这个环节比怎么调起摄像头更常被忽略。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











