在小程序的“兑换订单—出示核销码”功能中,我们遇到了一个典型问题:二维码在微信开发者工具中能够正常显示,但在安卓真机(小米手机)上点击后二维码区域为空白。
接口返回正常,核销码也已经生成,问题最终不在后端,而在小程序运行环境与二维码库的兼容性。
本文记录完整的排查过程,以及最终采用的兼容方案。
一、业务场景
在积分商城兑换商品后,可在“兑换订单”中点击“出示核销码”。页面会请求后端刷新一次临时核销码,并显示二维码和 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 物理
width、height不一致; - 新版 Canvas 2D 与旧版 Canvas API 混用;
- 真机基础库与开发者工具版本不同。
但本次问题更靠前:二维码库在绘制之前已经因为缺少 TextEncoder 失败。此时即使调整 Canvas 尺寸或 draw 回调,也无法解决问题。
排查顺序建议如下:
- 先确认后端是否返回核销码;
- 打开真机调试,优先查看 JavaScript 报错;
- 确认二维码矩阵是否已成功生成;
- 最后再检查 Canvas 的渲染时机与尺寸。
