HTML无法直接生成二维码,需用JavaScript调用qrcode.js等库将证书URL或base64数据转为Canvas/SVG;切勿嵌入超限PDF,应托管HTTPS页面并生成可验证短链。

HTML里怎么生成证书二维码
不能直接用 HTML 生成二维码——HTML 是标记语言,没编码能力。得靠 JavaScript 调用第三方库(比如 qrcode.js 或 qr-code-generator),把证书 URL 或 base64 数据转成 Canvas 或 SVG 图像。
常见错误是把证书 PDF 直接塞进二维码:体积超限(一般上限 3 KB),扫码失败。正确做法是把证书托管在 HTTPS 域名下,生成指向该页面的短链接或带签名的 token 链接。
- 优先用
https://yourdomain.com/cert?id=abc123这类服务端可验证的路径,别用本地file://或未加密的 HTTP 链接 - 若必须嵌入证书内容,先用
btoa()编码 JSON 字符串,再截断到 2.5 KB 以内(UTF-8 下中文占 3 字节,极易超) - 避免用
QRCode.toDataURL()在低版本 iOS Safari 上触发白屏——改用QRCode.toString()+ SVG 渲染更稳
扫码后如何在 HTML 页面展示电子证书
用户扫出来的必须是能直出证书的 HTML 页面,不是下载链接。重点不是“显示”,而是“可信展示”:防截图篡改、防链接盗用、支持离线校验。
关键点在于证书数据和签名分离。页面加载时用 fetch() 拿证书 JSON,用 Web Crypto API 验证 signature 字段是否匹配公钥,验证通过才渲染 <canvas></canvas> 或 PDF.js 加载内联 PDF。
立即学习“前端免费学习笔记(深入)”;
- 证书 JSON 至少含
id、name、issueDate、signature、issuerPubKey字段 - 别把私钥或完整签名逻辑写在前端——签名必须由服务端完成,前端只做验签
- PDF.js 加载 base64 PDF 时,需用
pdfjsLib.getDocument({ data: atob(pdfBase64) }),不能直接src到<iframe></iframe>
为什么手机扫码打不开或显示空白
90% 是 HTTPS 和 MIME 类型问题。微信、支付宝、iOS 相机等扫码工具默认拒绝非 HTTPS 页面;部分安卓浏览器对 text/html 响应头不严格,但 iOS 强制校验。
另一个隐蔽坑是证书页面用了 localStorage 存 token,但扫码打开的是无痕上下文(如微信内置浏览器),localStorage 为空导致白屏。
- 确保服务器返回
Content-Type: text/html; charset=utf-8,且没有X-Frame-Options: DENY - 禁用所有依赖第三方 cookie 的登录态判断,扫码页必须免登录或用 URL 参数透传临时凭证(如
?token=ey...&exp=17...) - 检查证书 JSON 接口是否被 CORS 拦截——用
credentials: 'omit',别设'include'
兼容性与性能要注意什么
低端安卓机(尤其 UC 浏览器)解析大 QR 码慢,Canvas 渲染超过 500×500 像素会卡顿;iOS 15+ 对 Web Crypto 支持完整,但 iOS 14 需要 fallback 到 subtle.digest() 验 SHA-256。
PDF.js 在弱网下加载慢,别让它阻塞证书信息渲染——先用纯 HTML 展示基本信息,PDF 区域加 loading 骨架屏。
- 二维码尺寸控制在 300×300 px 内,容错率选
M(15%),兼顾扫描率和数据容量 - 验签失败时,明确提示
"证书签名无效,请勿信任",而不是静默隐藏内容 - 不要用
new QRCode(...)初始化多次——重复调用会覆盖 DOM 节点,导致扫码页刷新后二维码消失
最麻烦的其实是证书更新机制:URL 不变但内容变了,用户扫旧码看到的还是缓存页。得在服务端加 ETag 或 Cache-Control: no-cache,前端加时间戳参数也行,但别忘了 CDN 配置同步。



















