从 NFC 阅读器直接读取到桌面 Web 应用程序?

Posted

技术标签:

【中文标题】从 NFC 阅读器直接读取到桌面 Web 应用程序?【英文标题】:Reading from an NFC reader directly into a desktop web application? 【发布时间】:2021-02-08 23:55:55 【问题描述】:

我让 LibNFC 在 Linux 终端上工作,识别我的 ACR122U 阅读器,我想知道是否有一种方法可以通过 Linux 桌面上的 Chrome 工作,因为它与 android 支持非常相似,具有所有 NFC 设备由 libnfc 完成的处理,浏览器只需要知道这个库,而不是每一种类型的 USB 或其他可以做 NFC 的设备。

我已经尝试使用 WebNFC API 来连接它:

document.getElementById("scanButton").addEventListener("click", async () => 
    log.innerhtml = "NFC Register started...";

    try 
      const ndef = new NDEFReader();
      await ndef.scan();
      log.innerHTML = ("> Scan started");
  
      ndef.addEventListener("readingerror", () => 
        log.innerHTML = ("Argh! Cannot read data from the NFC tag. Try another one?");
      );
  
      ndef.addEventListener("reading", ( message, serialNumber ) => 
        log.innerHTML = ("ID  $serialNumber logged @" + dt.toLocaleTimeString());   );
     catch (error) 
      log.innerHTML = (error);
    
  );

  document.getElementById("stopButton").onclick = function()
    log.innerHTML = "NFC Register stopped @ " + new Date().toLocaleTimeString();
    ; 

但我遇到了Error: NFC Permission Request denied

以及用于连接它的 WebUSB API:

var usbd = ;
let device;
let deviceEndpoint = 0x02;

let powerUpDevice = new Uint8Array([0x62,0x00, 0x00, 0x00, 0x00,0x00,0x00,0x01,0x00, 0x00]).buffer;
let getCardUID = new Uint8Array([0xff,0xca,0x00,0x00,0x04]).buffer;

(function() 
    'use strict';

    usbd.authorize = function()
        navigator.usb.requestDevice( filters: [ vendorId: 0x072f ] )
            .then(selectedDevice => 
                device = selectedDevice;
                console.log(device.configuration.interfaces[0].interfaceNumber);
                console.log(device.manufacturerName);
                console.log(device.productName);
                console.log(device);
                return device.open()
                    .then(() => 
                        if (device.configuration === null) 
                            return device.selectConfiguration(1);
                        
                    );
            )
            .then(() => device.claimInterface(0))

但我遇到了Error: ...blocked because it implements a protected interface class,即不支持,所以这是不行的。

有没有办法整合 libusb/libnfc 库或任何其他方法来直接连接 NFC 阅读器以读取到网络浏览器/应用程序?

【问题讨论】:

您需要用户下载或运行运行 localhost 网络服务器的程序,您的网络应用程序可以连接到该服务器以使用本地硬件 - 这就是戴尔服务标签查找功能的工作原理,例子。 哦,谢谢你的好例子;我认为这可能是我的 B 计划,但我真的希望它是一个独立的 Web 应用程序,无需安装额外的程序。至少那时它可以在多个平台上运行,但是非常感谢你的解决方案——如果一切都失败了,我会依靠它:) 您是否尝试过在 https:// 网络应用程序中运行您的 WebNFC 示例(例如,使用letsencrypt 免费证书)?据我了解,您需要处于安全环境中才能访问 NFC 阅读器(这就是为什么 WebNFC 在线实验应该从这个 https:// 配置的网站 googlechrome.github.io/samples/web-nfc 工作) @FSp 是的,我在 localhost 环境和 https 域地址中都使用该应用程序来测试应用程序。我认为这主要是 ACR122U 阅读器的问题...... 【参考方案1】:

Web NFC 自 2021 年 2 月起仅在 Android 上受支持。请参阅 https://web.dev/nfc/

WebUSB 错误表明您正在请求一个实现受保护类的接口(在以下这些类中):

  // USB Class Codes are defined by the USB-IF:
  // https://www.usb.org/defined-class-codes
  const uint8_t kProtectedClasses[] = 
      0x01,  // Audio
      0x03,  // HID
      0x08,  // Mass Storage
      0x0B,  // Smart Card
      0x0E,  // Video
      0x10,  // Audio/Video
      0xE0,  // Wireless Controller (Bluetooth and Wireless USB)
  ;

我想知道这是否是 linux 的事情,因为我能够通过 WebUSB 与 ACR122U 和 SCL3711 NFC 读取器 USB 设备进行通信。见https://github.com/beaufortfrancois/chrome-nfc

您有没有先尝试WebHID?见https://web.dev/hid

【讨论】:

您的 Chrome NFC 示例是否在 WebUSB 上运行?我认为 chrome.nfc.* 代码行意味着它适用于 Chrome 应用程序集合,而不是直接从网络上运行,如果这有意义吗?我试过了,它对我有用,但是 chrome-nfc.js 不能应用于在实时网站上运行的东西,对吧?关于 WebHID,我填写了 vendorID 和所有指向 ACR122U 的链接,但无法识别;我会继续努力并摆弄它,但没有运气:/ 正如您在github.com/googlearchive/chrome-nfc/compare/… 中所读到的,chrome-nfc.js 应该在浏览器环境中运行良好,因为它使用 WebUSB,而不仅仅是 Chrome 应用程序环境。 我在你的 repo 上尝试了使用 WebUSB 并在 Linux 和 Windows 上通过 Chrome 运行它的示例,但我不断收到相同的错误,即 NFC 阅读器是受保护的类和(Uncaught (in promise) DOMException: Access denied.) 所以我仍然不确定它是如何为您工作的,而且我认为也没有绕过它的方法。虽然奇怪的是,它在 Linux 上确实可以作为 Chrome 应用程序工作,但随着它被逐步淘汰,我认为我不会专注于开发,对吧? WebHID 似乎没有将阅读器视为“兼容设备”,所以我又回到了一个... 抱歉@François Beaufort 回复晚了! Linux 上的 ChromeNFC 示例:ibb.co/5LG8DhL Linux 上的 USB 内部屏幕:ibb.co/319857B Windows 上的 ChromeNFC 示例:ibb.co/9ncyzfc Windows 上的 USB 内部屏幕:ibb.co/Bg1JSsK Chrome 中的两个操作系统的站点信息:ibb.co/ZzJLpmG 是的,给你; Linux 窗口有两个 Interface 0 元素,一个在主要部分,另一个在配置描述符中:ibb.co/mJmxz5F/ibb.co/6Pw1Y5H。在 Windows 上,我只能读取主要部分的接口 0:ibb.co/Z1TBmWs

以上是关于从 NFC 阅读器直接读取到桌面 Web 应用程序?的主要内容,如果未能解决你的问题,请参考以下文章

NFC阅读器没有在android中连续读取NFC标签

Android 简单 NFC 阅读器应用程序源代码错误。它不会读取任何 nfc 标签?

使用 ACR122 NFC 阅读器读取苹果支付令牌

NFC Mifare Ultralight 读取/写入使用 ACR122 的普通 Java 桌面应用程序

使用 ACR1252U NFC 标签阅读器读取 NTag213 上的所有记录

acr122U NFC标签读取