如何从web-nfc API获取权限?

rxm*_*rxm 4 html javascript debugging nfc webnfc

我正在尝试让 Web NFC 通过Web NFC API工作,但无法通过以下错误消息:NotAllowedError: NFC permission request denied.

我在 Windows 10 计算机上的 Chrome 89 Dev 上使用它,源代码在本地运行。

我也尝试过互联网上发布的示例,包括Google 示例,但它返回相同的错误。我并不担心它目前处于实验阶段,因为提到这一点确实表明它已经成功通过了必要的测试,包括权限。

我正在使用的 HTML/JS 代码如下,我已经阅读了规范点 9.3,但我无法理解将其编写为代码,因此是否有一个指导算法可以帮助解决这个问题这?

async function readTag() {
  if ("NDEFReader" in window) {
    const reader = new NDEFReader();
    try {
      await reader.scan();
      reader.onreading = event => {
        const decoder = new TextDecoder();
        for (const record of event.message.records) {
          consoleLog("Record type:  " + record.recordType);
          consoleLog("MIME type:    " + record.mediaType);
          consoleLog("=== data ===\n" + decoder.decode(record.data));
        }
      }
    } catch(error) {
      consoleLog(error);
    }
  } else {
    consoleLog("Web NFC is not supported.");
  }
}

async function writeTag() {
  if ("NDEFWriter" in window) {
    const writer = new NDEFWriter();
    try {
      await writer.write("helloworld");
      consoleLog("NDEF message written!");
    } catch(error) {
      consoleLog(error);
    }
  } else {
    consoleLog("Web NFC is not supported.");
  }
}

function consoleLog(data) {
  var logElement = document.getElementById('log');
  logElement.innerHTML += data + '\n';
};
Run Code Online (Sandbox Code Playgroud)
<!DOCTYPE html>
<html>
<head>
<script src="webnfc.js"></script>
</head>
<body>

<p>
  <button onclick="readTag()">Test NFC Read</button>
  <button onclick="writeTag()">Test NFC Write</button>
</p>
<pre id="log"></pre>

</body>
</html>
Run Code Online (Sandbox Code Playgroud)

And*_*rew 5

来自https://web.dev/nfc/#security-and-permissions

Web NFC 仅适用于顶级框架和安全浏览上下文(仅限 HTTPS)。源端在处理用户手势(例如单击按钮)时必须首先请求“nfc”权限。如果先前未授予访问权限,则 NDEFReader scan() 和 write() 方法会触发用户提示。

我猜你是从一个file://URL 运行的,正如你所说的“本地”,这是不受支持的。
您需要使用https://URL从本地 Web 服务器托管它

一旦进入正确的范围,尝试扫描或写入应该会触发用户提示。

您还可以检查权限,请参阅https://web.dev/nfc/#check-for-permission

更新:
所以我尝试了示例页面https://googlechrome.github.io/samples/web-nfc/

这对我在启用了“实验性网络平台功能”的 Android Chrome 87 上有效

当您点击扫描按钮时,会弹出一个请求许可的对话框。

将此示例中的代码与您的代码进行比较,我注意到:-

ndef.addEventListener("reading" , ({ message, serialNumber }) => { ...
Run Code Online (Sandbox Code Playgroud)

就像你的那样:-

ndef.onreading = event => { ...
Run Code Online (Sandbox Code Playgroud)

我不知道这是否是事件发生的样式设置或其他什么(嘿,这都是实验性的)

Update2 从桌面支持的评论中回答问题。

因此,您目前应该使用一些桌面/浏览器组合,并且将来可能会有更广泛的支持,因为这不再是实验标准。显然,正如您的测试链接所建议的那样,Linux 桌面上的 Chrome 应该可以工作,因为这与 Android 支持非常相似,所有 NFC 设备处理都是由该库完成的,libnfc浏览器只需要了解这个库,而不是每种类型的 USB 或其他设备即可进行 NFC。

从 Windows 上的 NFC 支持来看,大部分都集中在通过 USB 直接控制 NFC 读取器,就像另一个 USB 设备一样,而 API 中有一个 libnfc 等效项,Windows.Networking.Proximity我还没有遇到任何 NFC 读取器说他们支持这个或任何使用它的人。

对于 Mac Deskstop,考虑到苹果在 iOS 中的 NFC 支持方面落后了,我觉得他们的桌面支持会更落后,尽管它可能与 Linux 类似。