开屏动画

微信小程序二维码真机不显示:从 `TextEncoder is not defined` 到跨端兼容方案

技术 0 评 38 度

在小程序的“兑换订单—出示核销码”功能中,我们遇到了一个典型问题:二维码在微信开发者工具中能够正常显示,但在安卓真机(小米手机)上点击后二维码区域为空白。

接口返回正常,核销码也已经生成,问题最终不在后端,而在小程序运行环境与二维码库的兼容性。

本文记录完整的排查过程,以及最终采用的兼容方案。

一、业务场景

在积分商城兑换商品后,可在“兑换订单”中点击“出示核销码”。页面会请求后端刷新一次临时核销码,并显示二维码和 16 位文字码;商户端扫描二维码后查询订单,再确认核销。

流程如下:

点击“出示核销码”
        ↓
后端生成新的随机核销码,只保存 SHA-256 摘要
        ↓
小程序展示二维码与文字码
        ↓
商户小程序扫码查询订单
        ↓
商户确认核销,核销码失效

后端接口返回示例如下:

{
  "code": 0,
  "message": "操作成功。",
  "data": {
    "id": 2,
    "order_no": "GC20260904135520A78667",
    "verification_code": "4e98e2a030b0aef5"
  }
}

可见,后端数据本身没有问题。

二、现象:开发者工具正常,真机二维码空白

初版实现采用常见的二维码库,在小程序中通过 Canvas 绘制二维码矩阵。

开发者工具中:

  • 接口返回正常;
  • 二维码可以显示;
  • 商户端可以扫码。

小米真机中:

  • 接口同样返回了 verification_code
  • 弹窗能打开;
  • 二维码没有显示。

真机调试控制台最终给出了关键报错:

TextEncoder is not defined

三、根因:二维码库依赖了真机不存在的 TextEncoder

二维码库在将字符串转换为 UTF-8 字节时,使用了浏览器环境常见的写法:

new TextEncoder().encode(data)

开发者工具通常带有更完整的 Web API 模拟,因此代码能够执行;但部分微信小程序真机运行环境没有全局 TextEncoder,二维码库在生成二维码矩阵前就抛出异常,后续 Canvas 自然没有任何内容可画。

这也是为什么“接口返回成功,但二维码空白”。

四、不要只盯着 Canvas

二维码真机空白时,很多人会先怀疑 Canvas 绘制时机、尺寸或 DPR。它们确实是高频问题,例如:

  • setData 后 Canvas 节点还没有创建完成;
  • draw() 未完成就导出临时图片;
  • CSS 尺寸和 Canvas 物理 widthheight 不一致;
  • 新版 Canvas 2D 与旧版 Canvas API 混用;
  • 真机基础库与开发者工具版本不同。

但本次问题更靠前:二维码库在绘制之前已经因为缺少 TextEncoder 失败。此时即使调整 Canvas 尺寸或 draw 回调,也无法解决问题。

排查顺序建议如下:

  1. 先确认后端是否返回核销码;
  2. 打开真机调试,优先查看 JavaScript 报错;
  3. 确认二维码矩阵是否已成功生成;
  4. 最后再检查 Canvas 的渲染时机与尺寸。

五、第一层修复:为二维码库补充 UTF-8 兼容编码

📅 那年今日·09月04日
广告图片
AD
快来做第一个评论的人吧~