web nfc 仅支持 ndef 消息层,不提供 uid、atqa 等原始标签数据访问;所有操作须由用户手势触发,且需 https 环境。

Web NFC 本身不提供“原始标签数据”(如 UID、ATQA、SAK 或底层 APDU 响应)的访问能力。它只处理标准化的 NDEF(NFC Data Exchange Format)消息层,所有读取操作都基于已解析的 NDEF 记录(如 text、url、mime 等)。所谓“原始数据”,比如芯片型号、内存页结构、防冲突信息等,属于协议栈底层,浏览器出于安全与抽象原则明确屏蔽了这部分接口。
为什么无法获取原始标签数据
这是 Web NFC 的设计边界,不是技术限制未达成:
- W3C Web NFC 规范从始至终只定义了
NDEFReader和NDEFWriter,不包含transceive()、getUid()或任何低级射频控制方法 - 浏览器沙箱禁止网页直接接触硬件指令,防止恶意克隆卡、嗅探或重放攻击
- Android/iOS 系统层也未向 WebView 或 Chromium 渲染进程暴露 ISO-DEP/ISO-14443 底层通道
- 所有“UID 可读”类需求,在 Web 环境中实际是通过 NDEF 消息中预写入的唯一标识符(如自定义文本 record)间接实现的
如何用 NDEF 数据驱动 DOM 状态迁移
虽然不能读 UID,但你可以把 NDEF 当作可靠、结构化的“事件源”,用它触发组件状态变化。关键在于:将标签内容映射为语义化动作,再交由前端框架或原生 JS 更新 DOM。
- 监听
reading事件后,立即解析event.message.records,按recordType和mediaType分类处理 - 对每条 record 调用
record.toText()或new TextDecoder().decode(record.data)获取字符串值 - 用该字符串作为 key 查询本地状态映射表,例如:
{ "door-main": "open", "room-light-01": "toggle" } - 调用
setState()(React)、store.dispatch()(Redux/DVA)或直接操作document.getElementById().className更新 UI - 建议在
onreading回调内做防抖(如 500ms 内忽略重复触发),避免同一张标签反复靠近导致状态抖动
真实可用的“类原始”数据提取技巧
若业务确实需要区分不同物理标签,可采用以下合规且跨平台方案:
- 制卡阶段:用工具(如 NFC Tools App)向每张 NTAG213 写入唯一 NDEF 文本记录,内容为短哈希(如
dev-7f2a9c),而非依赖 UID - 网页端:读取该文本 record 后,用其作为设备 ID 查询后端 API,拉取对应配置(如门禁权限、灯光分组、欢迎文案)
- 进阶用法:写入 MIME-type record(如
application/vnd.myapp.config),携带 JSON 字符串,包含版本号、生效时间、UI 主题等字段,前端解析后直接 patch 状态树
异步流程必须由用户手势启动
所有 Web NFC 操作必须绑定在显式用户交互之后(如按钮点击、触摸事件),不能自动运行。这是强制安全策略:
- 调用
reader.scan()前,确保已在 click/tap 回调中;否则会抛出SecurityError - HTTPS 是硬性要求(
localhost允许),HTTP 页面即使支持 API 也会静默失败 - 首次使用时,系统弹窗请求 “允许此网站使用 NFC”,用户拒绝后需手动在浏览器设置中开启
- 扫描成功后,
onreading是异步回调,内部所有 DOM 操作(如innerHTML = ...)天然处于微任务队列,无需额外await










