在 H5(HTML5)和 JavaScript 中实现手机端扫描二维码,目前最主流、最稳定的方案是调用微信内置的扫码接口(如果用户在微信内打开)或使用第三方 JS 库(如 jsQR、html5-qrcode 等)来调用摄像头并识别二维码。
以下是几种常见方案的详细说明:
✅ 方案一:微信内扫码(推荐,最简单)
如果用户是在 微信 中打开你的 H5 页面,可以直接调用微信 JS-SDK 的 scanQRCode 接口。
步骤:
-
引入微信 JS-SDK:
<script src="https://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script>
-
配置微信 JS-SDK(需后端签名):
wx.config({ debug: false, appId: 'YOUR_APPID', timestamp: 1234567890, nonceStr: 'YOUR_NONCE_STR', signature: 'YOUR_SIGNATURE', jsApiList: ['scanQRCode'] }); -
调用扫码:
wx.ready(function () { wx.scanQRCode({ needResult: 1, // 默认为0,扫描结果由微信处理,1则直接返回扫描结果 scanType: ["qrCode", "barCode"], // 可以指定扫二维码还是一维码,默认二者都有 success: function (res) { var result = res.resultStr; // 当needResult 为 1 时,扫码返回的结果 alert('扫码结果: ' + result); } }); });
⚠️ 注意:微信 JS-SDK 需要后端配合生成签名,且域名需配置到微信公众平台。
✅ 方案二:通用方案 使用 html5-qrcode 库(推荐跨平台)
如果用户不在微信内,或需要兼容所有浏览器,推荐使用开源库 html5-qrcode。
安装:
npm install html5-qrcode
或通过 CDN 引入:
<script src="https://unpkg.com/html5-qrcode"></script>
使用示例:
<div id="reader" style="width: 300px;"></div>
<button onclick="startScan()">开始扫码</button>
<button onclick="stopScan()">停止扫码</button>
<script>
let html5QrcodeScanner = null;
function startScan() {
html5QrcodeScanner = new Html5QrcodeScanner(
"reader",
{ fps: 10, qrbox: { width: 250, height: 250 } },
false
);
html5QrcodeScanner.render(onScanSuccess, onScanFailure);
}
function onScanSuccess(decodedText, decodedResult) {
// 扫码成功
alert('扫码结果: ' + decodedText);
stopScan(); // 可选:停止扫描
}
function onScanFailure(error) {
// 扫码失败(通常忽略,每帧都会触发)
console.warn(`扫码失败: ${error}`);
}
function stopScan() {
if (html5QrcodeScanner) {
html5QrcodeScanner.clear().then(() => {
console.log("扫码器已清除");
}).catch(err => {
console.error("清除扫码器失败: ", err);
});
}
}
</script>
✅ 优点:兼容所有现代浏览器,支持二维码和一维码,无需后端。
⚠️ 注意:需要 HTTPS 环境(本地开发可用 localhost)。
✅ 方案三:使用 jsQR 库(轻量级,需自行处理摄像头)
如果你需要更细粒度的控制(比如自定义 UI),可以使用 jsQR。
步骤:
-
引入 jsQR:
<script src="https://cdn.jsdelivr.net/npm/jsqr@1.4.0/dist/jsQR.min.js"></script>
-
获取摄像头画面并逐帧识别:
<video id="video" width="300" height="300" autoplay playsinline></video>
<canvas id="canvas" width="300" height="300" style="display:none;"></canvas>
<script>
const video = document.getElementById('video');
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
// 获取摄像头
navigator.mediaDevices.getUserMedia({ video: { facingMode: "environment" } })
.then(stream => {
video.srcObject = stream;
video.setAttribute("playsinline", true); // required to tell iOS safari we don't want fullscreen
video.play();
requestAnimationFrame(tick);
})
.catch(err => console.error("摄像头获取失败: ", err));
function tick() {
if (video.readyState === video.HAVE_ENOUGH_DATA) {
canvas.height = video.videoHeight;
canvas.
width = video.videoWidth;
ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
const code = jsQR(imageData.data, imageData.width, imageData.height, {
inversionAttempts: "dontInvert",
});
if (code) {
alert('扫码结果: ' + code.data);
// 停止扫描
video.srcObject.getTracks().forEach(track => track.stop());
}
}
requestAnimationFrame(tick);
}
</script>
✅ 优点:轻量,可自定义 UI。
⚠️ 缺点:需自行处理摄像头、帧率、性能优化等。
📌 总结对比
| 方案 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| 微信 JS-SDK | 微信内 H5 | 简单、稳定、原生体验 | 仅限微信,需后端签名 |
| html5-qrcode | 通用 H5 | 跨平台、易集成、功能全 | 包体积稍大(~100KB) |
| jsQR | 自定义需求 | 轻量、灵活 | 需自行处理摄像头和性能 |
🔐 注意事项
- HTTPS 要求:调用摄像头必须使用 HTTPS(localhost 除外)。
- 用户授权:首次调用需用户明确授权摄像头权限。
- 性能优化:避免每帧都处理图像,可适当降低帧率(如 5-10 FPS)。
- 兼容性:iOS Safari 需设置
playsinline属性。
首发原创文章,作者:世雄 - 原生数据库架构专家,如若转载,请注明出处:https://idctop.com/article/480344.html



