qrcode.js 快速入门指南,全面介绍在 Web 前端通过 qrcode.js 引入库文件、创建 DOM 容器、配置参数、生成及动态更新二维码的完整流程与排错方案。
qrcode.js 快速入门:安装与生成基础二维码
时间:2026-11-03
浏览:525
文章目录
一、工作机制与核心渲染链路
在很多早期 Web 业务中,生成二维码通常依赖服务器端接口(如 Python、Java 或 Go 生成图片后回传前端展示)。这种方式不仅消耗后端服务器算力与带宽,而且在弱网或高并发场景下容易产生明显的图片加载延迟。
qrcode.js 彻底转变了这一链路:它将二维码的矩阵计算与图形绘制完全下放至前端浏览器内部。其完整的执行管线包含输入解析、模式判定、Reed-Solomon 纠错码演算、矩阵掩模计算以及终端节点挂载等环节。
从架构图可以看出,qrcode.js 具有以下关键设计特点:
- 零外部网络请求:整个运算过程在前端闭环完成,生成的二维码可以直接通过 Canvas API 转换为 Base64 或二进制 Blob,保障了数据传输的私密性与离线可用性。
- 自适应渲染降级:默认检测浏览器是否支持 HTML5 Canvas 2D 绘图环境。如果处于老旧浏览器或特殊无 Canvas 宿主环境,库内部会自动降级为基于
<table>单元格着色,避免脚本运行报错中断。
二、安装与引入方式
在实际项目工程中,根据技术栈类型(传统多页应用或现代化单页工程),可选择最贴合的引入方式。
1. CDN 直接引入(传统 HTML / 多页项目)
对于不需要打包工具的静态页面或小型项目,直接在 HTML 页面中通过 <script> 标签从公共 CDN 加载压缩版本即可。代码如下:
<!-- 引入官方压缩版 qrcode.js -->
<script src="https://cdn.jsdelivr.net/npm/qrcodejs@1.0.0/qrcode.min.js"></script>
加载成功后,浏览器全局对象 window 上将直接挂载 QRCode 构造函数。
2. 本地静态资源离线引入
在内网系统或要求完全本地化部署的生产环境中,建议将 qrcode.min.js 下载至项目的静态资源目录(例如 /assets/js/qrcode.min.js),并在页面中使用相对路径引入:
<script src="./assets/js/qrcode.min.js"></script>
3. 前端工程化环境(npm / yarn)
在基于 Vue、React 或 Vite/Webpack 的工程化项目中,若需要通过包管理器管理依赖,通常安装经过现代模块化封装的衍生包(例如 qrcodejs2),或直接安装支持 Promise/TypeScript 的 qrcode 包:
# 安装兼容模块化导出的 qrcodejs 封装包
npm install qrcodejs2 --save
# 或安装现代标准 qrcode 包
npm install qrcode --save
在单文件组件中使用 ES Module 导入:
import QRCode from 'qrcodejs2';
三、生成基础二维码的完整步骤与代码
生成基础二维码主要包含四个核心环节:定义容器节点、引入资源库、调用构造函数、按需执行运行时更新。
完整可运行的 HTML 示例
下面是一个可以直接保存为 .html 文件并在浏览器中双击运行的完整代码示例:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>qrcode.js 基础二维码示例</title>
<style>
.qr-wrapper {
display: flex;
flex-direction: column;
align-items: center;
margin-top: 50px;
font-family: sans-serif;
}
#qrcode {
padding: 12px;
border: 1px solid #dcdfe6;
border-radius: 8px;
background: #ffffff;
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.05);
}
</style>
<!-- 引入 qrcode.js 库 -->
<script src="https://cdn.jsdelivr.net/npm/qrcodejs@1.0.0/qrcode.min.js"></script>
</head>
<body>
<div class="qr-wrapper">
<h3>扫描访问目标地址</h3>
<!-- 承载二维码的 DOM 容器 -->
<div id="qrcode"></div>
</div>
<script>
// 确保 DOM 结构解析完成后再执行初始化
window.addEventListener('DOMContentLoaded', function () {
// 1. 获取目标 DOM 节点
var container = document.getElementById("qrcode");
// 2. 实例化 QRCode 对象并配置基础参数
var qrcodeInstance = new QRCode(container, {
text: "https://example.com",
width: 160,
height: 160,
colorDark: "#345E82",
colorLight: "#ffffff",
correctLevel: QRCode.CorrectLevel.H
});
});
</script>
</body>
</html>
new QRCode(element, options) 时,第一个参数必须是真实的 DOM 节点(或者传入节点的 DOM id 字符串);如果传入为 null 或未挂载的虚拟节点,控制台会抛出 Cannot read property of null 错误。
四、核心参数配置与视觉调整
QRCode 构造函数的第二个参数是一个配置对象(Options),它决定了生成二维码的物理尺寸、色彩明暗对比以及纠错容灾能力。
| 参数名称 | 类型 | 默认值 | 作用说明与工程建议 |
|---|---|---|---|
text |
String | "" | 需要编码的目标文本或网址。字数越多,生成的点阵越密。 |
width |
Number | 256 | 生成的 Canvas 物理宽度(像素)。移动端页面建议不小于 160。 |
height |
Number | 256 | 生成的 Canvas 物理高度(像素)。通常与 width 保持 1:1 正方形比例。 |
colorDark |
String | "#000000" | 前景点阵模块颜色。必须与底色保持足够的明暗对比度(推荐高于 7:1)。 |
colorLight |
String | "#ffffff" | 背景衬底及静区留白颜色。建议保持纯白或浅色,不可设置为透明以免无法识别。 |
correctLevel |
Number | QRCode.CorrectLevel.L | 容错等级:L(7%)、M(15%)、Q(25%)、H(30%)。中间加 Logo 时必须使用 H。 |
特别需要注意 correctLevel(纠错等级)的选择权衡:
- QRCode.CorrectLevel.L:仅能恢复约 7% 的损坏数据。它的优点是生成的黑白矩阵格子最少、点阵最大,在极小尺寸下也能迅速识别。
- QRCode.CorrectLevel.H:最高级别的容错率,即使二维码被遮挡或污损 30%,识别算法依然能还原数据。当产品需求要求在二维码中心叠加企业 Logo 图标时,遮挡区域会损失数据,此时必须选用该级别。
五、动态更新与生命周期管理
在实际业务开发中,二维码的内容常常需要随着用户的操作发生变化(例如切换商品规格、输入框实时预览、支付订单超时刷新等)。许多初学者在动态更新时会反复调用 new QRCode(...),这会导致新的 Canvas 被不断追加到容器内,造成视图层层堆叠。
qrcode.js 提供了优雅的运行时更新接口:makeCode() 与 clear()。
1. 使用 makeCode() 动态重新绘制
// 页面初始化时创建一次实例
var qrcode = new QRCode(document.getElementById("qrcode"), {
text: "https://init.example.com",
width: 180,
height: 180
});
// 在按钮点击或定时器回调中,复用该实例更新内容
function refreshQrUrl(newUrl) {
// makeCode 内部会自动复用已建好的 Canvas 上下文,仅重绘像素点
qrcode.makeCode(newUrl);
}
2. 使用 clear() 清空画布
当需要隐藏二维码或准备重置状态时,调用 qrcode.clear() 可以清空当前绘制的点阵,避免旧的敏感内容遗留在用户界面上。
六、常见问题排查与解决清单
在项目集成与上线测试过程中,容易遇到空白、中文字符乱码、多次渲染堆叠以及手机端难以识别等问题。通过下述诊断树可快速定位并修复。
1. 报错:TypeError: Cannot read properties of null (reading 'appendChild')
原因排查:脚本执行时刻早于 HTML 元素挂载时刻,document.getElementById("qrcode") 返回了 null。
解决方案:将初始化逻辑包裹在 window.addEventListener('DOMContentLoaded', ...) 回调中;若在 Vue/React 框架中,务必在 mounted 或 useEffect 钩子函数内执行。
2. 中文字符扫码后呈现乱码或问号
原因排查:原生 qrcode.js 默认采用 ISO-8859-1(单字节编码)进行数据流切分,直接传入汉字等多字节 UTF-8 字符会导致字节截断。
解决方案:在传入文本前进行 UTF-8 编码预处理:
function toUtf8(str) {
var out = "", i, len, c;
len = str.length;
for (i = 0; i < len; i++) {
c = str.charCodeAt(i);
if ((c >= 0x0001) && (c <= 0x007F)) {
out += str.charAt(i);
} else if (c > 0x07FF) {
out += String.fromCharCode(0xE0 | ((c >> 12) & 0x0F));
out += String.fromCharCode(0x80 | ((c >> 6) & 0x3F));
out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F));
} else {
out += String.fromCharCode(0xC0 | ((c >> 6) & 0x1F));
out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F));
}
}
return out;
}
// 传入经过 UTF-8 转码清洗后的字符串
qrcode.makeCode(toUtf8("中文测试内容:订单号123456"));
3. 移动端扫码摄像头极难对焦或识别失败
原因排查:URL 参数过长且同时开启了 H 级容错,导致在 128px 的小画布上挤入了海量密集细小的点阵单元,手机镜头无法清晰捕捉。
解决方案:
- 将长链接转换为短链接服务(如减少无用跟踪参数)后再行编码;
- 在没有 Logo 遮挡需求时,将
correctLevel降至QRCode.CorrectLevel.M; - 适当调大画布尺寸至 200px 以上,保证每个点阵方块在物理屏幕上拥有至少 2~3 个物理像素。
七、总结
qrcode.js 凭借无依赖、体积小巧(压缩后不足 15KB)以及开箱即用的特点,至今仍是 Web 客户端二维码生成的高效方案。掌握其核心容器挂载规则、利用 makeCode() 维持单例更新、并在复杂文本输入时做好字符集预处理,即可保障页面在各种终端环境下稳定、快速地呈现标准二维码。
实用工具推荐
绿化、压缩、噪点和虚拟水印,自由调节做旧程度。
选择画质和输出格式,预览压缩前后的大小。