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

Angular集成html5-qrcode二维码扫描器时如何申请相机权限

Angular 集成 html5-qrcode 点击申请相机权限实现方案

前置依赖

先安装对应npm包:
npm install html5-qrcode --save

代码实现

组件模板(xxx.component.html)

直接写对应界面结构,绑定按钮点击事件:

<button 
  (click)="handleRequestPermission()"
  [disabled]="loading"
>
  {{ loading ? '申请中...' : 'Request Camera Permission(请求相机权限)' }}
</button>

<!-- 权限申请通过后再渲染扫码区域 -->
<div id="qr-scanner-box" *ngIf="permissionGranted" style="width: 500px;height: 400px;"></div>

<!-- 错误提示 -->
<p *ngIf="errorTip" style="color: red;">{{ errorTip }}</p>

组件逻辑(xxx.component.ts)

核心逻辑是通过html5-qrcode自带的getCameras方法触发浏览器原生权限申请,授权通过后再初始化扫码实例:

import { Component, OnDestroy } from '@angular/core';
import { Html5Qrcode } from 'html5-qrcode';

@Component({
  selector: 'app-qr-scan',
  templateUrl: './qr-scan.component.html'
})
export class QrScanComponent implements OnDestroy {
  loading = false;
  permissionGranted = false;
  errorTip = '';
  private scannerInstance: Html5Qrcode | null = null;
  private readonly SCANNER_ID = 'qr-scanner-box';

  async handleRequestPermission() {
    this.loading = true;
    this.errorTip = '';

    try {
      // 该方法调用时会自动触发浏览器相机权限弹窗
      const cameraList = await Html5Qrcode.getCameras();
      if (cameraList.length === 0) throw new Error('未检测到可用摄像头');
      
      this.permissionGranted = true;
      // 等dom渲染完成后初始化扫码器
      setTimeout(() => this.initScanner(cameraList[0].id), 0);
    } catch (e: any) {
      this.permissionGranted = false;
      // 匹配常见错误场景
      switch(e?.name) {
        case 'NotAllowedError':
          this.errorTip = '相机权限被拒绝,请在浏览器设置中开启权限后重试';
          break;
        case 'NotFoundError':
          this.errorTip = '当前设备未找到可用摄像头';
          break;
        default:
          this.errorTip = `权限申请失败:${e?.message || '未知错误'}`;
      }
    } finally {
      this.loading = false;
    }
  }

  private async initScanner(cameraId: string) {
    this.scannerInstance = new Html5Qrcode(this.SCANNER_ID);
    try {
      await this.scannerInstance.start(
        cameraId,
        { fps: 10, qrbox: {width: 250, height: 250} },
        (scanResult) => {
          // 扫码成功回调,写自己的业务逻辑即可
          console.log('扫码结果:', scanResult);
          this.closeScanner();
        },
        () => {} // 扫描过程中的帧错误无需处理
      )
    } catch (e) {
      this.errorTip = '摄像头启动失败,请刷新重试';
      this.permissionGranted = false;
    }
  }

  private async closeScanner() {
    if (this.scannerInstance?.isScanning) {
      await this.scannerInstance.stop();
      this.scannerInstance.clear();
    }
  }

  ngOnDestroy() {
    // 组件销毁时释放摄像头资源,避免后台占用
    this.closeScanner();
  }
}

踩坑提示

  • 相机API仅在localhost或HTTPS环境下可用,HTTP部署的页面除本地调试外会直接被浏览器拦截权限申请
  • 用户第一次拒绝权限后,后续点击按钮不会再弹出系统权限弹窗,需要引导用户点击地址栏左侧的权限开关手动开启
  • 不要提前初始化扫码实例,必须等用户点击按钮、权限申请通过、扫码区域dom渲染完成后再初始化,否则会报错

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 10:18:22