Back

如何生成和嵌入二维码

如何生成和嵌入二维码

您需要在 Web 应用程序中添加二维码。也许是用于支付流程、可分享链接或活动门票。问题不在于是否使用二维码,而在于如何在浏览器中可靠地生成二维码,同时避免扫描问题或安全隐患。

本文介绍了 JavaScript 中的客户端二维码生成,解释了何时使用 SVG 与 Canvas 输出,并讨论了影响扫描可靠性的实际约束条件。

核心要点

  • 使用成熟的库在 JavaScript 中生成二维码——不要从零开始构建编码逻辑
  • 选择 SVG 用于可缩放的 Web 嵌入,选择 Canvas 用于程序化图像处理
  • 遵守留白区域规范,保持对比度,并使用实际扫描设备进行测试
  • 为可访问性和安全性提供可见的备选方案

理解二维码生成与扫描的区别

在编写任何代码之前,需要区分两个独立的问题:生成扫描

生成完全在您的控制范围内。您使用 JavaScript 库将数据编码为二维码图像。这在所有现代浏览器中都能可靠运行。

扫描则不同。用于读取二维码的原生浏览器 API(如 Barcode Detection API)仍处于实验阶段,缺乏通用支持。如果您的应用程序需要扫描功能,请规划备选方案——通常是基于摄像头的 JavaScript 库或手动输入字段。

本文重点关注生成。在规划实现时,不要混淆这两者。

如何在 JavaScript 中生成二维码

有几个 JavaScript 库可以处理前端的二维码生成工作。常见选项包括 qrcode,支持客户端和服务器端生成;qrcode-generator,一个轻量级的纯 JavaScript 编码器;以及较旧但仍被广泛使用的 QRCode.js,用于简单的 Canvas 或 DOM 输出。这些都不是”标准”——每个库在打包大小、输出格式和自定义选项方面都有权衡。

一般模式如下:

  1. 导入您选择的库
  2. 传递要编码的数据(URL、文本、vCard 数据)
  3. 指定输出格式和尺寸
  4. 渲染到 DOM 元素或提取为 data URL

大多数库接受错误纠正级别(L、M、Q、H)的配置。更高的级别允许二维码在受损更多的情况下仍可扫描——如果您计划叠加 logo 或在纹理表面上打印,这很有用。

二维码:SVG 与 Canvas

在 Web 上嵌入二维码时,您通常会在三种输出格式之间选择:SVG、Canvas 或 PNG/data URL。

SVG 输出

SVG 通常是 Web 嵌入的最佳选择。矢量格式可以无限缩放而不会出现像素化,非常适合响应式布局和打印应用。无论显示尺寸如何,文件大小都保持较小。CSS 样式可以自然地工作。

使用 SVG 的场景:

  • 二维码以不同尺寸显示
  • 打印质量很重要
  • 需要基于 CSS 的样式或动画

Canvas 输出

Canvas 以特定分辨率渲染为位图。当您需要像素级控制或计划以编程方式将二维码与其他图形合成时,这很有效。

使用 Canvas 的场景:

  • 生成用于下载的图像
  • 需要直接操作像素
  • 与其他基于 Canvas 的图形集成

PNG/Data URL

Data URL 允许您将二维码嵌入为 base64 编码的图像字符串。这消除了额外的 HTTP 请求,但会增加 HTML 负载大小。适用于电子邮件模板或外部资源不可靠的场景。

影响扫描可靠性的实际约束

一个看起来正确的二维码可能仍然无法扫描。注意以下问题:

留白区域:二维码的边框周围需要空白空间——通常为四个模块宽。裁剪此边距会导致扫描失败。

对比度:规范假设深色模块在浅色背景上。反转颜色或低对比度组合会降低可靠性。目标是至少 4:1 的对比度。

尺寸:最小可扫描尺寸取决于观看距离和相机质量。对于屏幕显示,较小的尺寸可能在现代设备上有效,但结果取决于观看距离和相机质量。对于打印,根据预期的扫描距离进行计算。

Logo 叠加和重度样式化:在中心添加 logo 利用了错误纠正——扫描器将 logo 视为损坏并重建数据。这只在较高的错误纠正级别(Q 或 H)下有效,激进的样式化可能会超出可恢复的极限。务必进行彻底测试。

安全性和用户体验考虑

编码 URL 的二维码会带来钓鱼机会。用户在扫描前无法检查目标地址。如果您的应用程序从用户输入生成二维码,请验证和清理该输入。考虑在二维码旁边显示编码的 URL 作为可见文本。

为了可访问性,始终以替代格式提供编码信息。二维码旁边的可见链接可以服务于无法或不愿扫描的用户。

服务器端生成

虽然本文重点关注客户端方法,但服务器端生成有其合理用途:减少客户端打包大小、缓存生成的代码,或在没有 JavaScript 的环境中生成代码。Node.js、Python、Go 和大多数其他后端语言都有相应的库。输出格式的考虑保持不变。

结论

二维码生成的技术实现很简单。使用成熟的 JavaScript 库,而不是从零开始构建编码逻辑。选择 SVG 用于可缩放的 Web 嵌入,选择 Canvas 用于程序化图像处理。二维码的可靠性来自于遵守约束:保持留白区域,确保适当的对比度,并使用实际扫描设备进行测试。始终为可访问性和安全性提供可见的备选方案。

常见问题

错误纠正级别决定了二维码在保持可扫描的情况下可以承受多少损坏。L 可恢复约 7% 的损坏,M 恢复 15%,Q 恢复 25%,H 恢复 30%。在添加 logo 叠加或在纹理表面上打印时使用更高的级别(Q 或 H),因为扫描器将这些修改视为损坏并重建缺失的数据。

常见原因包括裁剪的留白区域(代码周围的空白边框)、深色和浅色模块之间的对比度不足,或对于扫描距离而言尺寸太小。确保边框周围至少有四个模块的空白空间,保持最低 4:1 的对比度,并在实际观看距离下使用真实设备进行测试。

客户端生成适用于大多数 Web 应用程序,并减少服务器负载。当您需要减少客户端打包大小、缓存生成的代码以供重用,或在没有 JavaScript 的环境中生成代码时,服务器端生成是有意义的。两种方法产生相同的输出——根据您的架构需求选择。

可以,但只能在较高的错误纠正级别(Q 或 H)下。扫描器将 logo 视为损坏,并使用错误纠正来重建数据。保持 logo 小巧、居中,并使用多个扫描应用程序进行彻底测试。激进的样式化或过大的 logo 可能会超出可恢复的极限,完全破坏扫描功能。

Understand every bug

Uncover frustrations, understand bugs and fix slowdowns like never before with OpenReplay — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data. Check our GitHub repo and join the thousands of developers in our community.

OpenReplay