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
相关产品推荐
相关产品推荐

