capture属性仅对type="file"有效,且必须配合accept指定image/、video/或audio/*等媒体类型才能触发摄像头或麦克风;合法值仅有"user"和"environment",其他如"camera"等已被废弃;https、用户手势触发及设备权限缺一不可,否则静默降级为图库选择。

capture 属性必须配合 type="file" 和精确 accept 才能生效
单独写 capture 或给 type="text" 加这个属性,浏览器会直接忽略。它只对 <input type="file"> 有效,且必须明确告诉浏览器“你要什么类型的数据”。accept="image/*" 是触发拍照界面的前提;accept="video/*" 才可能唤起录像;accept="audio/*" 对应录音。漏掉 accept,capture 就形同虚设。
常见错误写法:<input type="file" capture>(没 accept)、<input type="file" accept="image/jpeg" capture>(iOS 和部分 Android 会降级为图库选择)。推荐用 accept="image/*",兼容性最稳。
capture 值只能是 "user"、"environment" 或不带值
capture="camera"、capture="microphone" 这类写法早已被主流浏览器废弃,Chrome 和 Safari 都不认。W3C 规范只定义了两个合法字符串值:"user"(提示前置摄像头/面向用户的麦克风)和 "environment"(提示后置摄像头)。但要注意:
- iOS Safari 直到 16.4+ 才开始真正响应
capture="environment",旧版本直接忽略 - Android Chrome 多数支持
capture="environment",但微信 X5 内核基本不解析该值 - 不带值的
capture(即capture布尔属性)在 iOS 上通常等价于capture="user"
为什么点了还是弹出相册,而不是直接打开摄像头
这不是 bug,是平台统一策略:只要 accept="image/*" 存在,系统级弹窗就会同时提供「拍照」和「从相册选取」两个入口。capture 只是提示优先项,无法禁用相册选项。静默降级的常见原因包括:
- 页面不是
https://协议(HTTP 下 iOS Safari 和新版 Chrome 直接禁用媒体设备) - 触发
input.click()不在用户真实点击/触摸回调内(比如放在setTimeout或Promise.then里会被拦截) - input 元素不可见(
display: none或opacity: 0但未正确绑定 click) - Android 设备未在系统设置中开启「允许网站使用摄像头」权限(尤其国产 ROM,常藏在「应用管理→浏览器→权限管理」里)
真机调试时容易忽略的硬性条件
桌面端 DevTools 的 Device Mode 无法触发真实摄像头流,必须在真机上测试。另外三个关键点常被跳过:
-
input必须静态存在于 DOM 中,不能是 JS 动态插入后立刻.click()(iOS Safari 要求 input 已渲染且用户直触) - 首次访问需用户手动授权,若之前点过「拒绝」,后续调用不会再次弹窗,得进系统设置手动开
- 微信内置浏览器(WKWebView)在 iOS 上行为与 Safari 一致,Android 上则基本不支持
capture值,仅响应布尔形式
如果业务强依赖实时预览、多帧拍摄或绕过相册,capture 属性就不够用了——得切到 navigator.mediaDevices.getUserMedia(),但这意味着要自己处理权限请求、EXIF 方向修正、以及安卓 WebView 的兼容黑洞。











