web nfc仅支持ndef标准标签(如ntag213/215/216),不支持身份证、门禁卡等普通ic卡;需https或localhost环境,仅chrome for android v95+稳定支持,ios完全不支持;初始化前须检测'ndefreader' in window且协议为https或localhost;scan()为单次扫描,reading事件需立即绑定,record.data为arraybuffer,须用textdecoder解码;write()需用户手势触发且标签可写,不提供uid读取能力。

Web NFC 在绝大多数真实设备上无法直接读写普通 IC 卡(如身份证、门禁卡),它只支持符合 NDEF 标准的标签,且必须运行在安全上下文(https 或 localhost)中。浏览器支持极有限——目前仅 Chrome for Android(v95+)稳定支持 NDEFReader 和 NDEFWriter,iOS 完全不开放 Web NFC API。
如何检测和初始化 NDEFReader
别跳过检测步骤,否则用户点按钮时静默失败。先确认全局对象存在,再检查是否在 HTTPS 下运行:
-
'NDEFReader' in window为false时,说明浏览器不支持(包括所有 Safari、Firefox、Edge 桌面版) - 即使支持,
location.protocol !== 'https:' && location.hostname !== 'localhost'也会导致new NDEFReader()抛出SecurityError - 建议把初始化逻辑包裹在按钮点击中,避免页面加载即报错;不要在
DOMContentLoaded里直接 new 实例
scan() 调用后没反应?注意权限与触发时机
ndef.scan() 不是“一直监听”,而是单次扫描会话,持续约数秒,超时自动结束。常见失效场景:
- 用户未在系统设置中开启 NFC 开关(Android 设置 > 连接 > NFC)
- 页面未获得焦点:Chrome 要求 tab 处于激活态,切到后台或锁屏后扫描立即中断
- 标签类型不兼容:仅支持 NDEF 格式标签(如 NTAG213/215/216、MIFARE Ultralight C),不支持 Classic、DESFire、身份证等非 NDEF 卡
- 未正确处理
reading事件:事件只触发一次,需在scan()后立即绑定,不能延迟注册
读取到的数据是 ArrayBuffer,不是明文字符串
即使标签存的是文本,record.data 返回的也是 ArrayBuffer,必须用 TextDecoder 解码,且要留意编码声明:
- 记录中的
record.encoding字段可能为'utf-8'或'utf-16',但很多标签不写该字段,实际按 UTF-8 存储 - 错误写法:
String.fromCharCode(...new Uint8Array(record.data))—— 会乱码,尤其含中文时 - 正确写法:
new TextDecoder(record.encoding || 'utf-8').decode(record.data) - 若解码后为空字符串,先检查
record.data.byteLength是否为 0,再确认标签是否真写了 NDEF 数据(可用 NFC Tools App 验证)
write() 写入失败的三个硬性限制
NDEFWriter.write() 比读取更受限,失败几乎必然发生,除非同时满足:
- 用户主动触发(必须是用户手势,如 click/tap,不能由定时器或 Promise resolve 触发)
- 标签处于可写状态(NTAG213 默认可写,但部分已锁定或格式化为其他协议的标签会拒绝)
- Chrome 设置中已授权该站点使用 NFC(首次调用会弹出权限提示,用户拒绝后无二次提示)
- 写入内容必须符合 NDEF 规范:例如文本记录需带
encoding和language字段,URI 记录需以http://等标准 scheme 开头
最常被忽略的一点:Web NFC 不提供 UID 读取能力。所谓“读取卡片号”,对非 NDEF 标签(如大多数门禁卡)根本不可行——那需要原生 Android 的 NfcA/MifareClassic API,Web 层完全不可见。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











