capture="user" 必须搭配 accept="image/" 才可能生效,单独使用会被浏览器忽略;真正触发摄像头的关键是 accept="image/",https 和用户手势是硬性前提,getusermedia() 才是稳定可控的方案。

capture="user" 必须搭配 accept="image/*" 才可能生效
单独写 capture="user" 没用,浏览器会直接忽略。它只是个提示,不是指令,真正触发摄像头的关键是 accept="image/*" —— 这告诉浏览器“用户要选一张图”,系统才可能拉起相机界面。accept="image/jpeg" 或 accept="image/png" 在部分 Android 机型上也会降级为相册选择,iOS Safari 尤其敏感。
常见错误:<input type="file" capture="user">(漏 accept)、<input type="file" accept="*" capture="user">(accept="*" 被当作文档类型,不触发相机)。
HTTPS 和用户手势是硬性前提,缺一不可
HTTP 协议下,capture 在 Chrome 96+ 和 iOS Safari 中完全失效;localhost 可临时测试,但真机验证必须 HTTPS。另外,click() 调用必须发生在用户真实点击/触摸事件回调里,比如:button.addEventListener('click', () => input.click()) 是安全的,而 setTimeout(() => input.click(), 100) 或 Promise resolve 后调用,会被浏览器拦截。
常见静默失败现象:点击后弹出相册而非相机,控制台无报错——大概率是 HTTPS 缺失、触发上下文非用户手势,或页面被嵌在 iframe 里(iOS Safari 对 sandbox 限制极严)。
capture="user" 在 iOS 和 Android 行为差异极大
iOS Safari(14.5+)只认 capture="user",且强制前置,capture="environment" 直接被忽略;Android Chrome 部分版本支持 capture="environment" 尝试调后置,但实际是否生效取决于厂商 ROM 和系统相机 App 实现,不可靠。
别写 capture="true"、capture="front" 或 capture="camera" —— 这些非标准值所有现代浏览器都无视。W3C 规范只定义了 "user" 和 "environment" 两个合法字符串值。
更可靠的方案是 getUserMedia(),capture 已实质废弃
Chrome 96+ 已彻底禁用 capture 属性,Safari 仅旧版本支持,现在写 <input type="file" accept="image/*" capture="user">,多数设备只会打开文件选择器。真正可控的方式是 navigator.mediaDevices.getUserMedia():
async function startFrontCamera() {
try {
const stream = await navigator.mediaDevices.getUserMedia({
video: { facingMode: "user" }
});
video.srcObject = stream;
} catch (err) {
// 注意 err.name 可能是 'NotAllowedError'(权限拒绝)或 'NotFoundError'(无设备)
}
}
关键点:facingMode: "user" 明确请求前置;video 元素需设 autoplay 和 muted(iOS Safari 强制要求);拍照用 canvas.drawImage(video, ...) 前必须等 video.readyState === 4,否则黑图。
capture 属性表面简单,实际依赖一堆隐性条件,且已被主流浏览器逐步淘汰。真要稳定调前置摄像头,别绕弯子——直接上 getUserMedia(),虽然代码多几行,但行为可预期、权限可捕获、错误可处理。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











