大家好,很高兴又见面了,我是" 前端进阶 ",由我带着大家一起关注前端前沿、深入前端底层技术,大家一起进步,也欢迎大家关注、点赞、收藏、转发! NFC:一种无线通信技术,设备能够在不使用互联网的情况下相互通信前言 NFC(Near Field Communications) 代表近场通信,这是一种工作频率为 13.56 MHz 的短距离无线技术,可在距离小于 10 厘米的设备之间进行通信。 NFC 通信协议和数据交换格式基于现有的射频识别 (RFID) 标准,包括 ISO/IEC 14443 和 FeliCa。 NFC 标准包括 ISO/IEC 18092和 NFC 论坛定义的标准。1.什么是无源和有源NFC设备?1.1 无源NFC设备 包括NFC标签和其他小型发射器,它们可以向其他NFC设备发送信息,而不需要电源。但是,它们不能处理来自其他源的信息,也不能连接到其他无源设备。1.2 有源NFC设备 能够发送和接收数据,并且可以彼此通信,也可以与无源设备通信。目前来说,智能手机是最常见的有源NFC设备,其它常见的例子还包括公交读卡器和支付终端。2.Web NFC 的用户场景? 将设备靠近无源供电的 NFC 标签,以便读取或写入数据。 NFC工作原理是磁感应 NFC 的工作原理是使用磁感应,这意味着读取器(一个有源的、有源设备)会发出一个小电荷,然后产生一个磁场。 磁场为无源设备提供动力,无源设备将其转化为电脉冲来传输数据。 因此,当设备在范围内时,总是执行读取。 点对点连接以类似的方式工作,因为设备会定期切换到所谓的启动器模式以扫描目标,然后再回到目标模式。 如果找到目标,则读取数据的方式与读取标签的方式相同。 由于 NFC 基于现有的 RFID 标准,许多 NFC 芯片组支持读取 RFID 标签,但其中一些仅由单一供应商支持,而不是 NFC 标准的一部分。3.如何在浏览器使用NFC3.1 NDEFMessage对象 Web NFC API 的 NDEFMessage 接口表示已从 NFC 标签读取或写入的 NDEF 消息的内容。 通过调用 NDEFMessage() 构造函数或从传递给读取事件的 NDEFReadingEvent.message 属性获取实例。const ndefReader = new NDEFReader(); // 构造函数 function read() { // 创建一个读取单个标签然后停止轮询的函数,通过减少不需要的工作来节省电池寿命 return new Promise((resolve, reject) => { const ctlr = new AbortController(); ctlr.signal.onabort = reject; ndefReader.addEventListener("reading", (event) => { ctlr.abort(); resolve(event); }, { once: true }); ndefReader.scan({ signal: ctlr.signal }).catch((err) => reject(err)); }); } read().then(({ serialNumber }) => { console.log(serialNumber); });3.2 NDEFReader对象 Web NFC API 的 NDEFReader 接口用于从兼容的 NFC 设备读取和写入数据,例如支持 NDEF 的 NFC 标签,当这些设备在阅读器的磁场内时。 NDEFReader对象 下面的示例表示如何在通用读取处理程序和专门用于单次写入的处理程序之间进行协调。 为了写入,需要找到并读取标签。 这时您能够检查它是否真的是您要写入的标签。 这就是为什么建议从阅读事件中调用 write() 的原因。const ndef = new NDEFReader(); let ignoreRead = false; ndef.onreading = (event) => { if (ignoreRead) { return; // 写入挂起,忽略后续读取 } console.log("We read a tag, but not during pending write!"); }; function write(data) { ignoreRead = true; return new Promise((resolve, reject) => { ndef.addEventListener( "reading", (event) => { // 检查我们是否要写入此标签,或者拒绝 ndef .write(data) .then(resolve, reject) .finally(() => (ignoreRead = false)); // 将ignoreRead标志位设置为false }, { once: true } ); }); } await ndef.scan(); // NDEFReader 接口的 scan() 方法激活读取设备并返回一个 Promise,该 Promise 要么 // 在读取 NFC 标签时resolve,要么在遇到硬件或权限错误时reject。 // 如果先前未授予"nfc"权限,则此方法会触发权限提示。 try { await write("Hello World"); console.log("写入标签完成!"); } catch (err) { console.error("写入出错", err); } 3.3 NDEFRecord对象 Web NFC API 的 NDEFRecord() 构造函数返回一个新构造的 NDEFRecord 对象,该对象表示可以从兼容的 NFC 设备读取或写入的数据;例如支持 NDEF 的 NFC 标签。 new NDEFRecord(options)3.4 WebNFC的浏览器支持 如下图所示,只有Android设备上的Chrome浏览器支持WebNFC。虽然桌面版本的Chrome在80-88版本通过试验性标签"enable-experimental-web-platform-features "启动该特性,但是在后续的89版本以上都移除了对WebNFC的支持。所以,从长远来看WebNFC还有很长的路要走。 只有Android设备上的Chrome浏览器支持WebNFC 注意:很多设备没有配备 NFC 阅读器,则不会返回任何数据,即使浏览器可能支持该API。4.WebNFC示例4.1 HTML结构Web NFC 旨在为网站提供读取和写入 NFC 标签的能力,它们靠近用户的设备(通常为 5-10 厘米,2-4英寸)。 当前作用域仅限于 NDEF,一种轻量级二进制消息格式。 底层 I/O 操作(例如 ISO-DEP、NFC-A/B、NFC-F)和基于主机的 当前范围内不支持卡仿真 (HCE)。 4.2 完整JS代码scanButton.addEventListener("click", async () => { log("点击扫描按钮"); try { const ndef = new NDEFReader(); await ndef.scan(); log("> Scan started"); ndef.addEventListener("readingerror", () => { log("无法从 NFC 标签读取数据。 试试另一个?"); }); ndef.addEventListener("reading", ({ message, serialNumber }) => { log(`> Serial Number: ${serialNumber}`); log(`> Records: (${message.records.length})`); }); } catch (error) { log("Argh! " + error); } }); writeButton.addEventListener("click", async () => { log("用户点击写按钮"); try { const ndef = new NDEFReader(); await ndef.write("Hello world!"); // 写入数据 log("> Message written"); } catch (error) { log("Argh! " + error); } }); makeReadOnlyButton.addEventListener("click", async () => { log("用户点击设为只读按钮"); try { const ndef = new NDEFReader(); await ndef.makeReadOnly(); // 设置为只读 log("> NFC 标签已设为永久只读"); } catch (error) { log("Argh! " + error); } });5.总结 本文只是告诉大家什么是Web NFC,怎么使用它?因为笔者不是这方面的专家,很多内容也就浅尝辄止。但是文末的参考资料提供了大量优秀文档以供学习,如果有兴趣可以自行阅读。 参考资料 https://baijiahao.baidu.com/s?id=1639036926999857541 https://w3c.github.io/web-nfc/ https://developer.mozilla.org/en-US/docs/Web/API/NDEFReadingEvent/message https://developer.mozilla.org/en-US/docs/Web/API/NDEFReader https://developer.mozilla.org/en-US/docs/Web/API/NDEFRecord/NDEFRecord https://googlechrome.github.io/samples/web-nfc/ https://caniuse.com/?search=WebNFC