Chrome 90+ 要求 getUserMedia 必须在 HTTPS 或 http://localhost 下运行,127.0.0.1 不被信任;需正确处理 Promise 拒绝、检查 err.name;iframe 需加 allow="camera";并确认系统及 Chrome 相机权限已开启。

Chrome 浏览器中 navigator.mediaDevices.getUserMedia 被拒绝或静默失败
Chrome 90+ 默认禁止在非安全上下文(即非 https:// 或 localhost)调用摄像头 API。如果你的页面跑在 http://192.168.x.x、http://mydev.local 或直接双击打开的 file:/// 路径下,getUserMedia 会直接抛出 NotAllowedError 或根本不触发提示——连“是否允许”弹窗都不会出现。
- 仅
https://域名或http://localhost(含端口,如http://localhost:3000)被 Chrome 视为安全上下文 -
http://127.0.0.1不等价于localhost,Chrome 94+ 起已明确不信任127.0.0.1(除非显式加端口且服务支持) - 开发时可用
python3 -m http.server 8000 --bind 127.0.0.1:8000启服务,但必须用http://localhost:8000访问,不能用http://127.0.0.1:8000
调用 getUserMedia 时未正确处理 Promise 拒绝或权限状态
很多代码只写 .then(),忽略 .catch(),导致错误被吞掉。Chrome 在用户点击“拒绝”、设备被占用、或策略拦截时,都会 reject Promise,并附带具体 DOMException 名称。
navigator.mediaDevices.getUserMedia({ video: true })
.then(stream => {
video.srcObject = stream;
})
.catch(err => {
console.error('getUserMedia error:', err.name, err.message);
// 常见 err.name:NotAllowedError、NotFoundError、NotReadableError、SecurityError
});
-
NotAllowedError:用户拒绝 / 页面非安全上下文 / iframe 无allow="camera" -
NotFoundError:系统找不到可用摄像头(设备禁用、被占用、驱动异常) -
NotReadableError:摄像头正被其他进程(如 Zoom、OBS、另一个浏览器标签)占用 - 务必检查
err.name,而非只看err.message,因后者在不同 Chrome 版本中可能变化
iframe 嵌入页面时缺少 allow="camera" 属性
如果摄像头逻辑在 iframe 里运行(比如嵌入的微应用、第三方 SDK),Chrome 会强制要求该 iframe 显式声明能力许可,否则直接阻断调用。
-
allow="camera"是硬性要求,不加则getUserMedia立即失败 -
allow="camera *"表示允许所有源使用摄像头;若限制域名,可写allow="camera https://trusted.example.com" -
sandbox中必须含allow-scripts,否则 JS 根本无法执行
Chrome 设置或系统级摄像头权限被关闭
即使代码和上下文都正确,Chrome 自身或操作系统可能已全局禁用摄像头访问权限。
立即学习“前端免费学习笔记(深入)”;
- 手动检查路径:
chrome://settings/content/camera→ 确认“询问前先阻止”未开启,且你的站点未被设为“阻止” - macOS:系统设置 → 隐私与安全性 → 相机 → 确保 Chrome 在勾选列表中
- Windows:设置 → 隐私 → 相机 → “让应用访问相机”需开启,且 Chrome 列表中为“开”
- Linux(Wayland):部分发行版需额外安装
pipewire及xdg-desktop-portal,否则 Chrome 无法枚举设备
设备管理器里看到摄像头正常,不代表 Chrome 能用——它走的是独立的权限通道,且缓存较顽固。遇到疑似权限问题,先清空 chrome://settings/content/camera 下的站点权限,再刷新重试。











