案例一:二维码生成器

二维码生成器是第一个完整落地的 GenUI 小工具(单 HTML 形态,约 79KB)。它把经典开源库 qrcode-generator(v1.4.4,MIT,作者 Kazuhiko Arase)离线内联进产物,让用户粘贴文字/网址后实时得到二维码。复盘它的几个关键决策与踩坑,对同类「生成器」工具很有参考价值。

选型:离线内联成熟库

没有自己造二维码编码轮子,而是内联了经过广泛验证的 qrcode-generator。但内联前做了一件事:核查风险 API。确认该库不含 eval、不联网、不读写存储,纯算法实现,符合平台禁止项清单后才选用。这步核查在 genui check 之外,是「第三方库合规」的必要人工把关。

踩坑一:中文 UTF-8 编码(最致命)

默认情况下 qrcode.stringToBytes 走的是单字节编码,中文等多字节内容会被错误切分,扫码结果是乱码。必须用 UTF-8 编码函数:

qrcode.stringToBytesFuncs['UTF-8'] = function(s) {
    // 标准 UTF-8 字符串转字节数组实现
    ...
};
// 关键一行:覆盖默认编码
qrcode.stringToBytes = qrcode.stringToBytesFuncs['UTF-8'];

加上这一行后,中文字符串才能被正确编码进二维码。这是二维码类工具上线前最容易翻车的点,务必验证「中文扫码正常」。

踩坑二:canvas 绘制与转图合规

生成后的二维码用 canvas 绘制,再把 canvas 转成 img 元素显示。转图要用 canvas.toDataURL('image/png') 生成 Data URL——平台规定 Data URL 仅限图片使用,这是合规的。同时二维码需带白底 + 4 个模块宽的安静区(quiet zone),保证可被各类扫码器识别。

elImg.setAttribute('src', canvas.toDataURL('image/png'));

踩坑三:合规整改(从「能跑」到「过 check」)

初版能跑,但 genui check 会拦。整改动作:

  • 字号全部改用 --cos-text-body(14px)/ --cos-text-body-lg(16px)token,去掉所有硬编码字号;
  • 纠错等级选择从自写的按钮改为官方 radio.html 分段控件;分类切换改为 tabs.html(分段控件本体仍是 radio);
  • CSS 做到零硬编码颜色(QR 白底由 canvas 像素自带,不算 CSS 硬编码);
  • 修复 QR 图溢出 bug:.qr-box 需用 height:100% 而非 max-height。

验证闭环:截图反解

生成类工具不能只「看起来对」,要确认「扫出来对」。实战闭环:

  1. 用无头 Edge 对 genui preview 起的端口截图;
  2. 用 Node 脚本(jsqr + pngjs)对截图里的二维码反解;
  3. 断言反解出的 URL / 中文与输入完全一致(MATCH YES)。

整改后复测,二维码反解仍 MATCH YES,genui check 双卡通过。

小结

二维码生成器的经验浓缩成三条:第三方库先查风险 API、中文务必切 UTF-8 编码、生成结果用「截图反解」做真实验证。这三点能避开生成器类工具 90% 的上线坑。