"谁能想到,浏览器居然能直接管 USB?科技这碗饭,越来越难吃了!"
什么是 WebUSB?
WebUSB 是一项让浏览器直接与 USB 设备通信的技术,旨在缩短开发者和设备间的距离。无需安装驱动,无需依赖复杂的桌面软件,直接通过 JavaScript 和 USB 设备交互。是不是听起来很酷?但别着急,这背后还有不少坑等着你跳。
快速上手:连接 USB 设备
以下是 WebUSB 的基本使用流程,使用了现代的 async/await
语法,让代码更清晰易懂。
1. 请求设备连接
navigator.usb.requestDevice()
是一个用于请求用户连接 USB 设备的 API。你可以通过设置 filters
来限制可连接的设备。
const connectToDevice = async () => {
const filters = [
{ vendorId: 0x1234, productId: 0x5678 } // 根据你的设备填写
];
try {
// 请求用户选择并授权连接设备
const device = await navigator.usb.requestDevice({ filters });
console.log(`连接成功:${device.productName}`);
// 打开设备的连接
await device.open();
console.log('设备已打开');
// 选择设备的配置编号,通常为 1
await device.selectConfiguration(1);
console.log('配置已选择');
// 声明接口,以便进行数据传输
await device.claimInterface(0);
console.log('接口已被声明');
return device;
} catch (error) {
console.error('连接失败:', error);
}
};
// 示例调用
const device = await connectToDevice();
2. 发送数据
transferOut()
是用于向 USB 设备发送数据的 API。数据通常以 ArrayBuffer
或 TypedArray
的形式传递。
const sendData = async (device, data) => {
try {
const endpointNumber = 1; // 数据发送的端点编号,需参考设备文档
const encoder = new TextEncoder();
// 发送数据到设备的指定端点
await device.transferOut(endpointNumber, encoder.encode(data));
console.log('数据已发送:', data);
} catch (error) {
console.error('发送数据失败:', error);
}
};
// 示例调用
await sendData(device, 'Hello, USB!');
3. 接收数据
transferIn()
是用于从 USB 设备接收数据的 API。你需要指定接收的端点编号和数据的最大长度。
const receiveData = async (device) => {
try {
const endpointNumber = 1; // 数据接收的端点编号,需参考设备文档
// 从设备的指定端点接收数据,最大长度为 64 字节
const result = await device.transferIn(endpointNumber, 64);
const decoder = new TextDecoder();
// 将接收到的 ArrayBuffer 数据解码为字符串
console.log('接收到的数据:', decoder.decode(result.data));
} catch (error) {
console.error('接收数据失败:', error);
}
};
// 示例调用
await receiveData(device);
4. 释放设备
releaseInterface()
用于释放设备的接口。
const releaseDevice = async (device) => {
try {
// 释放设备的接口
await device.releaseInterface(0);
console.log('接口已释放');
// 关闭设备连接
await device.close();
console.log('设备已关闭');
} catch (error) {
console.error('释放设备失败:', error);
}
};
// 示例调用
await releaseDevice(device);
浏览器兼容性问题
说到 WebUSB,兼容性是避不开的话题。以下是目前主流浏览器的支持情况:
浏览器 | 是否支持 WebUSB 和 WebHID |
---|---|
Chrome | 是 |
Edge | 是 |
Firefox | 否(不支持,开发者请流泪) |
Safari | 否(想都别想) |
Opera | 是 |
友情提示
-
WebUSB 和 WebHID 都只被 Chromium 内核浏览器支持,意味着如果你的用户群体用的是 Firefox 或 Safari,你需要考虑降级方案,比如桌面客户端。
-
开发前记得检查 Can I Use 网站确认最新兼容性。
WebUSB vs. WebHID:两兄弟的恩怨情仇
WebUSB 和 WebHID 都是让浏览器与硬件交互的技术,但它们各有分工:
特性 | WebUSB | WebHID |
用途 | 通用 USB 设备通信 | 专注于人机接口设备 |
复杂性 | 配置复杂,协议自由度高 | 配置简单,专注特定类型 |
使用场景 | 自定义设备、工业设备 | 键盘、鼠标、手柄等输入设备 |
什么时候用 WebUSB?
-
自定义设备:当你的设备不遵循任何现成标准协议,比如需要与某些传感器或工业设备通信时。
-
高灵活性场景:当你需要完全掌控设备协议时。
什么时候用 WebHID?
-
标准人机接口设备:如果你的设备已经符合 HID 标准,比如键盘、鼠标、游戏手柄。
-
快速开发:HID 协议内置了一些简单的抽象,减少了繁琐的配置工作。
避坑指南
-
设备权限问题
-
WebUSB 的设备访问是基于用户授权的,所以每次页面刷新后可能需要重新请求权限。一定要和用户解释清楚:"不是我偷数据,是 USB 设备太严格!"
-
-
数据格式匹配
-
USB 通信对数据格式要求严格。如果设备文档写了用 Uint8Array,你就别用 String,发送错了可是没有撤回的。
-
-
浏览器限制
-
Safari 和 Firefox 的无情拒绝让 WebUSB 和 WebHID 的适用范围大打折扣。如果你的用户群体覆盖这些浏览器,建议提供降级方案,比如桌面客户端。
-
总结
WebUSB 是一项令人兴奋的技术,但也是一把双刃剑。它可以极大简化设备与用户的交互流程,但也带来了诸如兼容性、权限和复杂性的问题。而 WebHID 作为更专注的技术,为某些特定场景提供了便捷方案。总之,如果你准备跳进 WebUSB 或 WebHID 的坑,那就挽起袖子,用代码说话!
最后,记住:别轻易尝试跟设备讲道理,设备永远是对的!
关注我微信公众号————>花吕观学前端
标签:初体验,const,await,device,console,WebUSB,插上,设备 From: https://blog.csdn.net/Hua_Lvguan/article/details/144584802