HTML仅安全展示扫码入口,真伪校验必须由后端或第三方平台完成;二维码内容应为短时效、带签名的跳转链接,由后端生成并返回,前端仅渲染;禁用JS动态生成、禁用localStorage/URL传凭证,确保验证响应来自权威HTTPS接口。

HTML 本身不能验证证书真伪,它只是展示“扫码验证”入口的容器;真伪校验必须由后端服务或第三方验证平台完成,前端只负责把用户扫码后的结果(比如证书编号)传过去。
怎么在 HTML 里安全呈现“扫码验证”入口
用户扫的是二维码,但二维码内容必须是可被验证平台识别的结构化参数,不是随便一个链接。常见错误是把 https://example.com/verify?id=123 这类带明文 ID 的 URL 直接转成码——一旦 ID 被爬取或重放,就可能绕过权限控制。
- 二维码内容应为短时效、带签名的跳转链接,例如:
https://verify.example.com/v2?token=abc123&exp=1718945600&sig=def456 - 前端不生成 token 或 sig,这些必须由后端 API 返回,HTML 只做渲染和触发扫码
- 用
<img>标签直接嵌入静态二维码图最稳妥;避免用 JS 动态生成(易被篡改或拦截) - 如果用
<canvas>或 JS 库实时生成,务必确保原始数据(如证书编号)不暴露在 HTML 源码或 DevTools 中
用户扫码后,前端如何配合验证流程
扫码本质是打开一个外部页面(通常是微信内嵌浏览器或系统浏览器),所以 HTML 页面本身不参与校验逻辑。但你要让这个跳转过程可控、可追踪、防伪造。
- 二维码指向的地址必须是验证方提供的官方域名,禁止跳转到任意第三方或可被中间人劫持的地址(比如检查
verify.example.com是否在白名单中) - 可在 HTML 中加一层轻量级状态提示,比如用
data-cert-id属性存证书唯一标识:<div class="qr-box" data-cert-id="CERT-2024-7890">,供后续埋点或调试用 - 不要在 HTML 里写死任何密钥、API 密钥或签名算法细节——这些全属后端职责,前端泄露等于直接交出验证钥匙
为什么不能用 localStorage 或 URL 参数传递验证凭证
有人想让扫码后自动回跳到原页并带上结果,于是把验证结果塞进 URL hash 或 localStorage,这会引入严重风险。
立即学习“前端免费学习笔记(深入)”;
- URL 参数容易被截获、篡改、分享,
https://site.com/result?valid=true&cert_id=xxx这种结构毫无可信度 -
localStorage是同源隔离的,扫码跳转后新页面无法读取原页的localStorage,除非用 postMessage 配合 iframe,但复杂度陡增且兼容性差 - 真正的验证响应必须来自权威接口的 HTTPS 响应体,比如调用
/api/v1/cert/verify返回{"status":"verified","issued_at":"2024-05-01"},前端只负责展示这个结果
最容易被忽略的一点:二维码图片的 src 地址本身是否经过 CDN 缓存?如果缓存了带签名的动态链接,过期后用户扫出来的就是无效凭证——所以要么禁用该资源的 CDN 缓存,要么让二维码图本身是静态的,靠后端接口返回一次性 token 再跳转。











