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

Posted

技术标签:

【中文标题】您如何从 web-nfc API 获取权限?【英文标题】:How do you obtain permissions from web-nfc API? 【发布时间】:2020-12-13 00:32:43 【问题描述】:

我正在尝试让 Web NFC 通过Web NFC API 工作,但我无法通过NotAllowedError: NFC permission request denied. 的错误消息来处理它

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

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

我正在使用的 html/JS 代码如下,我已经阅读了specification point 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';
;
<!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>

【问题讨论】:

【参考方案1】:

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

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

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

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

您也可以查看权限查看https://web.dev/nfc/#check-for-permission

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

这适用于我在启用了“实验性 Web 平台功能”的 android Chrome 87 上

当您点击扫描按钮时,会弹出一个询问权限的对话框。

将此示例中的代码与您的代码进行比较,我发现确实如此:-

ndef.addEventListener("reading" , ( message, serialNumber ) =>  ...

和你一样:-

ndef.onreading = event =>  ...

我不知道是样式设置在 Event 上发生了什么还是其他什么(嘿,这都是实验性的)

更新2 回答来自桌面支持的 cmets 的问题。

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

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

对于 Mac Deskstop,鉴于 Apple 在 ios 中的 NFC 支持方面落后,我认为他们的桌面支持将更加落后,即使它可能类似于 Linux。

【讨论】:

好的,所以我已经集成了权限代码并将其托管到 tina.rf.gd (检查页面的源代码),现在我不确定发生了什么,因为我什至不能让它在控制台或用户提示中显示任何内容。 更新了答案,因为我能够让其他一些示例代码工作。 搞乱了代码,我终于让它与您的代码更改一起工作;谢谢你!你认为这些结果可以在桌面浏览器上重复吗?我已经看到桌面 Chrome 支持的许多成功(例如wpt.fyi/results/…),但我不确定为什么它没有以相同的方式处理它,即使使用连接的 NFC 阅读器:// 添加了关于桌面支持的更新,因为测试结果的链接显示 Linux 上的 Chrome 支持应该和 Android 上的一样好(因为引擎盖它们真的是一回事) 嘿@andrew 我刚刚读回你关于在 Linux 上运行的 libnfc 的最新答案;似乎您对如何有机会在浏览器中链接 libnfc 有粗略的想法?我让它在终端上独立工作,我正在试图弄清楚如何将它整合到 Web 应用程序中,那么你有什么建议吗?【参考方案2】:

正如您在 https://web.dev/nfc/#browser-support 上看到的那样,Web NFC 目前仅支持 Android,这就是您在 Windows 上收到 "NotAllowedError: NFC permission request denied." 错误的原因。

【讨论】:

很高兴知道,谢谢!-- Windows 支持和 API 是否正在进行任何试验? 暂时没有。

以上是关于您如何从 web-nfc API 获取权限?的主要内容,如果未能解决你的问题,请参考以下文章