返回正文 🌟 一、什么是
Are you an LLM? You can read better optimized documentation at /zh-CN/blog/2025-12/html5-qrcode.md for this page in Markdown format
H5页面实现二维码/条形码扫描
html5-qrcode 是一个轻量、高效、纯前端的 二维码/条形码扫描库,专为在网页(H5)中实现摄像头扫码功能而设计。
🌟 一、什么是 html5-qrcode?
html5-qrcode 是一个基于 HTML5 和 JavaScript 的开源库,它利用浏览器的 MediaDevices.getUserMedia() API 访问设备摄像头,实时扫描二维码(QR Code)和条形码(Barcode),无需安装插件或 App。
- ✅ 纯前端实现
- ✅ 支持手机和桌面浏览器
- ✅ 不依赖 jQuery 或其他框架
- ✅ 轻量、易集成
✅ 二、核心功能
| 功能 | 说明 |
|---|---|
| 🔍 扫描二维码(QR Code) | 支持标准 QR Code,可识别 URL、文本、联系方式等 |
| 📏 扫描条形码 | 支持 Code 128, Code 39, EAN-13 等常见格式(依赖底层引擎) |
| 📱 手机端友好 | 自动适配移动端摄像头(前后置可选) |
| 🖥 桌面端支持 | 支持 PC 浏览器调用摄像头扫码 |
| 🎯 自定义扫描区域 | 可设置 qrbox 限制扫描范围,提升体验 |
| 📦 纯 JS 实现 | 无依赖,仅 100KB 左右,加载快 |
| 🔌 支持多种集成方式 | CDN、npm、UMD、ES6 模块 |
📦 三、支持的码制(Barcode Formats)
html5-qrcode 底层使用了 ZXing (Zebra Crossing) 的 JavaScript 实现来解码,因此支持多种格式:
✅ 二维码(2D)
qr_code(最常用)
✅ 条形码(1D)
code_128(快递单、物流常用)code_39ean_8,ean_13(商品条码)upc_a,upc_eitf(Interleaved 2 of 5)codabar
⚠️ 注意:部分格式识别率受图像质量影响。
🚀 四、快速使用示例
引入方式一:CDN(最简单)
html
<script src="https://unpkg.com/html5-qrcode/html5-qrcode.min.js"></script>1
HTML 结构
html
<div id="qr-reader" style="width: 300px"></div>
<div id="qr-reader-results"></div>1
2
2
JavaScript 扫码
javascript
function onScanSuccess(decodedText, decodedResult) {
// 扫码成功
console.log(`扫码结果: ${decodedText}`);
document.getElementById('qr-reader-results').innerHTML =
`<p>结果: ${decodedText}</p>`;
}
function onScanFailure(error) {
// 失败回调(可选)
console.warn(`扫码失败: ${error}`);
}
// 初始化
new Html5Qrcode("qr-reader").start(
{ facingMode: "environment" }, // 使用后置摄像头
{
fps: 10, // 每秒扫描次数
qrbox: 250 // 扫描框大小(px)
},
onScanSuccess,
onScanFailure
).catch(err => {
console.error("启动摄像头失败:", err);
});1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
🎨 五、常用配置项(config)
| 配置项 | 说明 |
|---|---|
| fps | 每秒扫描帧数(建议 10~20) |
| qrbox | 扫描区域大小,可设为数字(正方形)或对象 {width: 300, height: 150} |
| formats | 指定只扫描某些码制,如 ['qr_code', 'code_128'] |
| aspectRatio | 摄像头预览宽高比,如 1.333(4:3) |
| disableFlip | true 禁用图像翻转(适用于某些设备镜像问题) |
🛠 六、高级用法
只扫描条形码(如快递单)
ts
new Html5Qrcode("qr-reader").start(
{ facingMode: "environment" },
{
fps: 10,
qrbox: { width: 300, height: 100 }, // 横向长条
formats: ["code_128", "code_39", "ean_13"] // 只识别条形码
},
(decodedText) => { /* 处理结果 */ }
);1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
扫描一次后停止
js
onScanSuccess(decodedText, result) {
console.log(decodedText);
// 停止扫码
html5QrCode.stop().then(() => {
console.log("扫码结束");
});
}1
2
3
4
5
6
7
2
3
4
5
6
7
切换摄像头
js
// 获取摄像头列表
Html5Qrcode.getCameras().then(devices => {
if (devices && devices.length > 0) {
const rearCamera = devices.find(d => d.label.toLowerCase().includes("back"));
html5QrCode.start(rearCamera.id, config, success, error);
}
});1
2
3
4
5
6
7
2
3
4
5
6
7
📱 七、兼容性
| 环境 | 是否支持 |
|---|---|
| 现代浏览器 | ✅ Chrome、Firefox、Safari、Edge |
| 移动端 | ✅ Android Chrome、iOS Safari(需 HTTPS) |
| 微信内置浏览器 | ✅ 支持(需 HTTPS + 用户授权) |
| HTTP 环境 | ❌ 大多数浏览器禁止摄像头访问 |
| 低版本 IE | ❌ 不支持 |
🔐 必须在 HTTPS 或 localhost 下运行,否则浏览器会拒绝摄像头权限。
📦 八、安装方式
npm 安装(推荐用于 Vue/React 项目)
bash
npm install html5-qrcode1
js
import Html5Qrcode from 'html5-qrcode';1
CDN 引入(H5 快速集成)
html
<script src="https://unpkg.com/html5-qrcode/html5-qrcode.min.js"></script>1
✅ 九、适用场景
| 场景 | 说明 |
|---|---|
| 🔗 网页扫码登录 | 如后台系统扫码登录 |
| 📦 快递单号扫描 | H5 页面扫描条形码录入单号 |
| 💳 支付码扫描 | 扫描支付宝/微信付款码(需合规) |
| 🎟 电子票核销 | 活动签到、电影票扫码验证 |
| 🏷 商品溯源 | 扫码查看商品信息 |
⚠️ 十、注意事项
- 必须 HTTPS:生产环境必须部署在 HTTPS 域名下。
- 用户授权:首次使用需用户允许摄像头权限。
- 性能优化:避免在低性能设备上长时间运行。
- 错误处理:处理摄像头不可用、无权限等异常。
- 移动端体验:建议全屏扫描,避免页面滚动干扰。
📊 十一、与其他库对比
| 库名 | 特点 | 适用场景 |
|---|---|---|
| html5-qrcode | 轻量、易用、功能全 | 通用扫码,推荐首选 |
| zxing-js/library | 更底层,灵活但复杂 | 需要高度定制 |
| quaggaJS | 支持条形码强,但维护弱 | 老项目 |
| instascan | 依赖 webrtc,已归档 | 不推荐新项目 |
✅ 总结
html5-qrcode 是目前 最推荐的前端扫码库,优点:
- ✅ 简单易用,文档清晰
- ✅ 支持二维码和条形码
- ✅ 适合 H5、Vue、React、微信公众号
- ✅ 社区活跃,持续维护
📌 如果你需要在网页中实现扫码功能,html5-qrcode 是首选方案!
案例
项目基于vue3框架开发:
安装html5-qrcode
bash
npm install html5-qrcode1
页面代码实现
vue
<template>
<div class="registration-container">
<h2>快递登记</h2>
<el-form label-position="top" :model="ruleForm" :rules="rules" ref="ruleFormRef">
<el-form-item label="真实退回快递单号" prop="expressNumber">
<el-input v-model="ruleForm.expressNumber" placeholder="请输入快递单号" clearable>
<template #suffix>
<SvgIcon @click="startScan" name="take-pictures" width="24" height="24" />
</template>
</el-input>
</el-form-item>
<el-form-item label="快递公司" prop="expressCompany">
<el-input v-model="ruleForm.expressCompany" placeholder="请输入快递公司" clearable />
</el-form-item>
</el-form>
<div class="footer">
<el-button class="submit-btn" type="primary" style="width: 100%" @click="submitForm">提交</el-button>
</div>
</div>
<!-- 全屏扫码层 -->
<div v-if="scanning" class="scanner-container">
<div id="qr-reader" ref="qrReaderRef"></div>
<p class="scan-hint">请将快递单条形码对准扫描框</p>
<el-button class="close-btn" @click="stopScan">关闭</el-button>
</div>
</template>
<script lang="ts" setup>
import { ref, onUnmounted, reactive } from 'vue'
import { Html5Qrcode } from 'html5-qrcode'
import { type FormInstance, type FormRules, ElMessage } from 'element-plus'
defineOptions({
name: 'after-sales-registration'
})
const ruleFormRef = ref<FormInstance>()
const ruleForm = reactive({
expressNumber: '',
expressCompany: ''
})
const rules = reactive<FormRules>({
expressNumber: [{ required: true, message: '请输入快递单号', trigger: 'blur' }],
expressCompany: [{ required: true, message: '请输入快递公司', trigger: 'blur' }]
})
const scanning = ref(false)
const qrReaderRef = ref(null)
let html5QrCode: Html5Qrcode | null = null
// 开始扫描
const startScan = (event: Event) => {
// 阻止事件冒泡和默认行为,防止输入框获得焦点
event.preventDefault()
event.stopPropagation()
if (scanning.value) return
scanning.value = true
// 如果有活动的输入框,尝试让它失去焦点
if (document.activeElement instanceof HTMLElement) {
document.activeElement.blur()
}
// 延迟确保 DOM 渲染
setTimeout(() => {
try {
html5QrCode = new Html5Qrcode('qr-reader')
const config = {
fps: 10,
qrbox: { width: 300, height: 100 }, // 横向长条,适合条形码
formats: [
'code_128', // ✅ 快递单最常用
'code_39', // ✅ 部分快递使用
'ean_13' // ✅ 商品类快递
]
}
html5QrCode
.start(
{ facingMode: 'environment' }, // 后置摄像头
config,
(decodedText) => {
// console.log('🎉 识别到快递单号:', decodedText)
ruleForm.expressNumber = decodedText
stopScan() // 自动关闭
},
() => {}
)
.catch((err) => {
ElMessage.error('摄像头启动失败:' + (err.message || '未知错误'))
scanning.value = false
stopScan()
})
} catch (err) {
ElMessage.error(`扫码库初始化失败,请重试${err}`)
stopScan()
}
}, 300)
}
// 停止扫描
const stopScan = () => {
if (html5QrCode) {
html5QrCode
.stop()
.then(() => {
html5QrCode?.clear()
html5QrCode = null
scanning.value = false
})
.catch(() => {
// console.error('停止失败:', err)
scanning.value = false
})
} else {
scanning.value = false
}
}
const submitForm = () => {
ruleFormRef.value?.validate((valid) => {
if (valid) {
// TODO:提交事件
} else {
ElMessage.error('请填写完整信息')
}
})
}
// 组件卸载时确保关闭扫描
onUnmounted(() => {
if (html5QrCode) {
html5QrCode.stop()
}
})
</script>
<style lang="scss" scoped>
.registration-container {
width: 100%;
height: 100%;
padding: 20px;
background: #f8f8fa;
box-sizing: border-box;
.footer {
position: fixed;
bottom: 0;
left: 0;
width: 100%;
padding: 17px 0;
text-align: center;
box-shadow: 0px -4px 16px 0px rgba(60, 126, 254, 0.2);
box-sizing: border-box;
.submit-btn {
width: 50% !important;
background: #3c7efe;
border-radius: 555px;
}
}
}
input {
width: 100%;
padding: 12px;
margin: 10px 0;
border: 1px solid #ddd;
border-radius: 6px;
font-size: 16px;
box-sizing: border-box;
text-align: center;
background-color: #f9f9f9;
}
button {
width: 100%;
padding: 12px;
background-color: #d32f2f;
color: white;
border: none;
border-radius: 6px;
font-size: 16px;
cursor: pointer;
}
button:disabled {
background-color: #ef5350;
cursor: not-allowed;
}
button:hover:not(:disabled) {
background-color: #c62828;
}
/* 全屏扫码层 */
.scanner-container {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: black;
z-index: 9999;
display: flex;
flex-direction: column;
align-items: center;
justify-content: flex-start;
padding-top: 40px;
}
#qr-reader {
width: 100%;
max-width: 500px;
border-radius: 12px;
overflow: hidden;
}
.scan-hint {
color: #4caf50;
margin-top: 12px;
font-size: 18px;
font-weight: bold;
}
.close-btn {
margin-top: 12px;
padding: 8px 16px;
background: #ff5252;
color: white;
border: none;
border-radius: 4px;
font-size: 14px;
}
</style>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
其他
注意事项
- 必须 HTTPS:生产环境必须部署在 HTTPS 域名下。
- 用户授权:首次使用需用户允许摄像头权限。
- 性能优化:避免在低性能设备上长时间运行。
- 兼容性问题:在某些旧版浏览器可能不支持。
- 移动端体验:
html5-qrcode扫码体验一般,需要贴紧条形码。
其他方案对比
| 方案 | 技术栈 | 是否推荐 | 说明 |
|---|---|---|---|
1. html5-qrcode + 格式过滤 | 纯前端 JS | ✅✅✅ 强烈推荐 | 轻量、易用、支持条形码 |
2. ZXing JS(原生) | 纯前端 JS | ✅ 推荐 | 功能强大,但配置复杂 |
3. 原生 getUserMedia + QuaggaJS | 纯前端 JS | ⚠️ 可用但不推荐 | QuaggaJS 已停止维护 |
| 4. 调用微信 JS-SDK 扫码 | 微信内置 | ✅ 限微信环境 | 依赖微信 App |
| 5. 调用 App 原生能力(Hybrid) | WebView + Native | ✅ 高性能 | 需开发 App |
| 6. 拍照上传 + 后端识别 | 前端 + 后端 | ✅ 稳定兜底 | 适合弱网或兼容性差的设备 |
V 0.11.10 |
MIT Licensed版权所有 © 2009-2025 CMONO.NET
本站访客数
--次 本站总访问量
--人次 