简体   繁体   English

有没有办法让 Chrome “忘记”一个设备来测试 navigator.usb.requestDevice, navigator.serial.requestPort?

[英]Is there a way to get Chrome to “forget” a device to test navigator.usb.requestDevice, navigator.serial.requestPort?

I'm hoping to migrate from using WebUSB to SerialAPI (which is explained nicely here ).我希望从使用WebUSB迁移到SerialAPI这里很好地解释了)。

Current Code:当前代码:

try {
    let device = await navigator.usb.requestDevice({
    filters: [{
            usbVendorId: RECEIVER_VENDOR_ID
        }]
    })
    this.connect(device)
} catch (error) {
    console.log(DEVICE_NAME + ': Permission Denied')
}

New Code:新代码:

try {
    let device = await navigator.serial.requestPort({
    filters: [{
            usbVendorId: RECEIVER_VENDOR_ID
        }]
    })
    this.connect(device)
} catch (error) {
    console.log(DEVICE_NAME + ': Permission Denied')
}

The new code appears to work, but I think it's because the browser has already requested the device via the old code.新代码似乎可以工作,但我认为这是因为浏览器已经通过旧代码请求了设备。

I've tried restarting Chrome as well as clearing all of the browsing history.我尝试重新启动 Chrome 并清除所有浏览历史记录。 Even closed the USB-claiming page and claimed the device with another app (during which it returns the DOMException: Unable to claim interface error), but Chrome doesn't seem to want to ask again.甚至关闭了 USB 声明页面并使用另一个应用程序声明了该设备(在此期间它返回DOMException: Unable to claim interface错误),但 Chrome 似乎不想再次询问。 It just happily streams the data with the previous connection.它只是愉快地使用先前的连接流式传输数据。

My hope was that using SerialAPI would be a way to avoid fighting over the USB with other processes, or at least losing to them.我希望使用 SerialAPI 可以避免与其他进程争夺 USB,或者至少输给它们。

Update更新

I had forgotten about:我忘记了:

Failed to execute 'requestPort' on 'Serial': "Must be handling a user gesture to show a permission request"

Does this mean that the user will need to use a button to connect to the device via SerialUSB?这是否意味着用户需要使用按钮通过 SerialUSB 连接到设备? I think with WebUSB I was able to make the connect window automatically pop up.我认为使用 WebUSB 我能够使连接 window 自动弹出。

For both APIs, as is noted in the update, a user gesture is required in order to call the requestDevice() or requestPort() method.对于这两个 API,如更新中所述,需要用户手势才能调用requestDevice()requestPort()方法。 It is not possible to automatically pop up this prompt.无法自动弹出此提示。 (If there is that's a bug so please let the Chrome team know so we can fix it.) (如果存在错误,请告知 Chrome 团队,以便我们修复它。)

Permissions granted to a site through the WebUSB API and Web Serial API are currently tracked separately so permission to access a device through one will not automatically translate into the other.通过 WebUSB API 和 Web 序列号 API 授予站点的权限当前单独跟踪,因此通过一个设备访问设备的权限不会自动转换为另一个。

There is not currently a way to programatically forget a device permission.目前没有办法以编程方式忘记设备权限。 That would require the navigator.permissions.revoke() method which has been abandoned.这将需要已被放弃的navigator.permissions.revoke()方法。 You can however manually revoke permission to access the device by clicking on the "lock" icon in the address bar while visiting the site or going to chrome://settings/content/usbDevices (for USB devices) and chrome://settings/content/serialPorts (for serial ports).但是,您可以通过在访问站点时单击地址栏中的“锁定”图标或转到 chrome://settings/content/usbDevices(对于 USB 设备)和 chrome://settings/ 手动撤销访问设备的权限content/serialPorts(用于串行端口)。

To get Chrome to "forget" the WebUSB device previously paired via navigator.usb.requestDevice API:要让 Chrome “忘记”之前通过 navigator.usb.requestDevice API 配对的 WebUSB 设备:

  1. Open the page paired to the device you want to forget打开与您想忘记的设备配对的页面
  2. Click on the icon in the address bar点击地址栏中的图标
  3. Click x next to device.单击设备旁边的 x。 If nothing is listed, then there are no paired devices for this web page.如果未列出任何内容,则此 web 页面没有配对设备。 在此处输入图像描述

The new code was NOT working.新代码不起作用。 It just appeared to be because Chrome was already paired with the port via the old code.这似乎是因为 Chrome已经通过旧代码与端口配对 There is no way the "new code" could have worked because, as noted in Kalido's comment, the SerialAPI (due to its power) requires a user gesture to connect. “新代码”不可能起作用,因为正如 Kalido 的评论中所指出的,SerialAPI(由于其强大的功能)需要用户手势来连接。

The code I'm using to actually connect and get data is basically built up from a few pieces from the above links in the OP:我用来实际连接和获取数据的代码基本上是由 OP 中上述链接的几部分组成的:

navigator.serial.addEventListener('connect', e => {
  // Add |e.target| to the UI or automatically connect.
  console.log("connected");
});

navigator.serial.addEventListener('disconnect', e => {
  // Remove |e.target| from the UI. If the device was open the disconnection can
  // also be observed as a stream error.
  console.log("disconnected");
});

console.log(navigator.serial);

document.addEventListener('DOMContentLoaded', async () => {

    const connectButton = document.querySelector('#connect') as HTMLInputElement;

    if (connectButton) {
        connectButton.addEventListener('click', async () => {
            try {
        
                // Request Keiser Receiver from the user.
                const port = await navigator.serial.requestPort({
                    filters: [{ usbVendorId: 0x2341, usbProductId: not_required }]
                });
            
                try {
                    // Open and begin reading.
                    await port.open({ baudRate: 115200 });
                
                } catch (e) {
                    console.log(e);
                }
                while (port.readable) {
                  const reader = port.readable.getReader();

                  try {
                    while (true) {
                      const { value, done } = await reader.read();
                      if (done) {
                        // Allow the serial port to be closed later.
                        reader.releaseLock();
                        break;
                      }
                      if (value) {
                        console.log(value);
                      }
                    }
                  } catch (error) {
                    // TODO: Handle non-fatal read error.
                    console.log(error);
                  }
                }
            } catch (e) {
              console.log("Permission to access a device was denied implicitly or explicitly by the user.");
              console.log(e);
              console.log(port);
            }
        }
}

The device-specific Vendor and Product IDs would obviously change from device to device.设备特定的供应商和产品 ID 显然会因设备而异。 In the above example I have inserted an Arduino vendor ID.在上面的示例中,我插入了一个 Arduino 供应商 ID。

It doesn't answer the question of how to get Chrome to "forget", but I'm not sure if that's relevant when using SerialAPI because of the required gesture.它没有回答如何让 Chrome “忘记”的问题,但由于需要手势,我不确定在使用 SerialAPI 时这是否相关。

Hopefully someone with more experience will be able to post a more informative answer.希望有更多经验的人能够发布更多信息的答案。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 WebUSB:如果navigator.usb.getDevices()失败,如何调用navigator.usb.requestDevice() - WebUSB: How to call navigator.usb.requestDevice() if navigator.usb.getDevices() fails 使用 navigator.usb.getDevices() 时,Chrome WebUSB API 不返回任何设备 - Chrome WebUSB API returns no device when using navigator.usb.getDevices() 有没有办法在Chrome中设置默认的捕获设备,例如navigator.setUserMedia()? (谷歌浏览器) - Is there a way to set default capture device in Chrome like navigator.setUserMedia()? (GOOGLE CHROME) navigator.device未定义 - navigator.device is undefined 测试导航器属性是否被吸气剂覆盖的可靠方法 function - Reliable way to test if navigator properties are overwritten with a getter function 是否有使用navigator.serial的示例网站? - Is there an example site that uses navigator.serial? 使用 navigator.serial 进行串行通信时的读取性能延迟 - Delayed read performance when using navigator.serial for serial communication 串行 API 中 navigator.serial 和 SerialPort 上的函数是否未实现? - Are functions on navigator.serial and SerialPort in Serial API unimplemented? 在 Chrome、Firefox 或 IE 上更改 navigator.platform 以测试操作系统检测代码 - Change navigator.platform on Chrome, Firefox, or IE to test OS detection code 如何更改 Chrome 设置以使用 navigator.language 进行测试 - How can I change Chrome settings to test using navigator.language
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM