You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Chrome的浏览器访问摄像头时出现Permissions Policy违规问题

问题描述

仅在Chrome系浏览器中调用摄像头时触发Permissions Policy违规,Safari和Firefox可正常运行。错误信息如下:

[Violation] Permissions policy violation: camera is not allowed in this document.
Error accessing the camera: DOMException: Permission denied

相关代码片段:

JS代码

const scanner = document.getElementById('scanner');
const qrCanvas = document.getElementById('qr-canvas');
const qrDataElement = document.getElementById('qr-data');
const scanMenuItemCamera = document.getElementById('scan');
const menuItemsCamera = document.querySelectorAll('.menu-item');
let cameraStream = null;

function startCameraFeed() {
  if (scanner && qrCanvas) {
    const videoConstraints = {
      facingMode: 'environment',
      width: 1280,
      height: 720
    };

    if (window.location.protocol === 'https:') {
      navigator.mediaDevices.getUserMedia({
          video: videoConstraints
        })
        .then(stream => {
          scanner.srcObject = stream;
          scanner.addEventListener('play', scanCodes);
          cameraStream = stream;

          const videoElement = document.getElementById('scanner');
          const zoomSlider = document.getElementById('zoomSlider');

          zoomSlider.addEventListener('input', (event) => {
            const scale = parseFloat(event.target.value);
            videoElement.style.transform = `scale(${scale})`;
          });

          videoElement.style.transform = 'translateZ(0)';
        })
        .catch(error => console.error('Error accessing the camera:', error));
    } else {
      console.error('Please use a secure connection (HTTPS) to access the camera.');
    }
  }
}

document.addEventListener('DOMContentLoaded', () => {
  startCameraFeed();

  menuItemsCamera.forEach(menuItemCamera => {
    menuItemCamera.addEventListener('click', () => {
      if (menuItemCamera.id === 'scan') {
        startCameraFeed();
      } else {
        stopCameraFeed();
      }
    });
  });

  function stopCameraFeed() {
    if (cameraStream) {
      cameraStream.getTracks().forEach(track => track.stop());
      cameraStream = null;
    }
  }

  scanMenuItemCamera.addEventListener('click', startCameraFeed);
});

HTML代码

<div id="controls">
  <input type="range" id="zoomSlider" min="1" max="5" step="0.01" value="1">
</div>

<video id="scanner" autoplay=""></video>
<canvas id="qr-canvas"></canvas>
<div id="qr-data" class="background"></div>

<a class="menu-item" id="scan"></a>
解决方案

Chrome对Permissions Policy的执行比其他浏览器更严格,可从以下几个方向排查修复:

  • 检查服务器HTTP头部:确保返回的Permissions-Policy头部包含camera=()(允许所有来源访问摄像头),或者根据需求指定特定来源,比如camera=(self)仅允许本站点。如果服务器配置了限制摄像头的策略,Chrome会直接拒绝请求。

  • 添加HTML meta标签:如果无法修改服务器配置,可在HTML的<head>中添加meta标签声明权限策略:

    <meta http-equiv="Permissions-Policy" content="camera=()">
    
  • 检查Chrome站点权限:手动确认当前站点在Chrome中的摄像头权限是否被禁用。操作路径:点击地址栏左侧的锁图标 → 「网站设置」→ 找到「摄像头」选项,设置为「允许」。

  • 优化代码逻辑:当前代码在DOMContentLoaded时自动调用startCameraFeed,同时scan按钮又绑定了该方法,可能导致重复发起权限请求引发冲突。可修改逻辑,确保仅在用户主动触发(比如点击按钮)时请求摄像头权限,避免页面加载时自动请求:

    document.addEventListener('DOMContentLoaded', () => {
      // 移除自动调用startCameraFeed()
      menuItemsCamera.forEach(menuItemCamera => {
        menuItemCamera.addEventListener('click', () => {
          if (menuItemCamera.id === 'scan') {
            startCameraFeed();
          } else {
            stopCameraFeed();
          }
        });
      });
    
      function stopCameraFeed() {
        if (cameraStream) {
          cameraStream.getTracks().forEach(track => track.stop());
          cameraStream = null;
        }
      }
    
      scanMenuItemCamera.addEventListener('click', startCameraFeed);
    });
    

内容的提问来源于stack exchange,提问作者NDi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 10:04:51