一、引言
随着 Web 技术的进步,WebHID(Web Human Interface Device) API 的出现让开发者可以直接通过浏览器与 USB 或蓝牙 HID 设备(如键盘、鼠标、游戏手柄等)进行交互。过去,我们只能通过浏览器访问远程服务器,或者使用外部应用与硬件进行通信。但现在,Web 应用可以利用 WebHID 与硬件设备直接进行数据交换,带来了更丰富的用户体验和应用场景。
本文将详细介绍 WebHID 的常用 API,重点讲解如何通过 WebHID 与鼠标和键盘设备进行交互,并提供相应的代码示例,帮助你在项目中实现硬件交互功能。
二、需求背景
Web 应用的功能越来越丰富,但传统的 Web 技术(如 JavaScript 和 HTTP)并不适用于所有硬件交互场景。尤其是对于需要直接与物理设备交互的应用,如游戏控制器、工业设备控制、可穿戴设备等,传统方法往往需要安装额外的驱动或原生应用。
WebHID 为 Web 开发者提供了新的解决方案,允许开发者直接访问 HID 设备,打破了 Web 和硬件设备之间的隔阂。通过 WebHID,我们可以轻松实现与鼠标、键盘等设备的交互,提升 Web 应用的功能和用户体验。
三、工作原理
WebHID API 使得浏览器能够直接与本地的 HID 设备(如键盘、鼠标、游戏手柄等)进行通信。其工作原理可以分为以下几个步骤:
1. 请求设备
开发者首先通过 navigator.hid.requestDevice() 方法向用户请求连接一个 HID 设备。这个方法会弹出一个设备选择框,用户可以选择要连接的设备。你可以使用设备过滤器来指定要连接的设备类型(例如,只选择键盘或鼠标设备)。
2. 授权设备访问
浏览器会要求用户授权 Web 应用访问所选择的设备。只有用户明确授权后,Web 应用才能获得设备的控制权。
3. 设备连接和数据传输
设备连接成功后,开发者可以通过 HIDDevice.open() 打开设备,并通过 inputreport 事件获取设备的数据。例如,键盘按键数据、鼠标移动数据等。
- 输入报告(Input Report):设备通过输入报告将其状态传输给 Web 应用。
- 输出报告(Output Report):Web 应用可以通过输出报告向设备发送命令或数据。
4. 断开连接
当不再需要与设备通信时,可以通过 HIDDevice.close() 方法断开设备连接。
四、WebHID 常用 API 介绍
WebHID API 主要通过以下几个核心方法来与 HID 设备进行交互:
-
navigator.hid.requestDevice():请求访问 HID 设备,弹出设备选择框,用户选择设备后返回设备对象。 -
HIDDevice.open():打开连接的设备,准备进行数据交互。 -
HIDDevice.close():关闭连接的设备。 -
HIDDevice.sendReport():向设备发送数据,常用于输出命令。 -
HIDDevice.addEventListener('inputreport', callback):监听来自设备的输入报告,获取设备数据。 -
HIDDevice.removeEventListener('inputreport', callback):移除输入报告的监听器。
示例代码(获取设备并进行交互)
javascript
// 请求连接 HID 设备
async function requestDevice() {
try {
const device = await navigator.hid.requestDevice({
filters: [{ usagePage: 0x01, usage: 0x06 }] // 只选择游戏手柄或相关设备
});
console.log('设备已连接:', device);
return device;
} catch (err) {
console.error('设备连接失败:', err);
}
}
// 打开设备并监听输入报告
async function connectDevice(device) {
try {
await device.open();
console.log('设备已打开');
// 监听设备输入报告
device.addEventListener('inputreport', (event) => {
const { reportId, data } = event;
console.log(`设备报告ID: ${reportId}`);
console.log(`设备数据: ${new Uint8Array(data.buffer)}`);
});
} catch (err) {
console.error('设备连接失败:', err);
}
}
// 发送数据到设备
async function sendDataToDevice(device, reportId, data) {
try {
await device.sendReport(reportId, data);
console.log('数据已发送:', new Uint8Array(data.buffer));
} catch (err) {
console.error('发送数据失败:', err);
}
}
// 断开连接
async function disconnectDevice(device) {
try {
await device.close();
console.log('设备已断开');
} catch (err) {
console.error('设备断开失败:', err);
}
}
五、键盘和鼠标设备的交互
1. 键盘设备数据读取
键盘设备通常会通过输入报告(input report)发送按键信息。每当用户按下或松开键盘上的按键时,设备会生成一个报告,并通过 WebHID 的 inputreport 事件进行传递。
假设我们要监听键盘的按键输入,可以通过 inputreport 事件获取键盘的扫描码(scan codes),从而知道用户按下了哪些键。
获取键盘按键数据的代码示例:
javascript
async function requestKeyboardDevice() {
try {
const device = await navigator.hid.requestDevice({
filters: [{ usagePage: 0x01, usage: 0x06 }] // 匹配键盘设备
});
console.log('键盘设备已连接:', device);
return device;
} catch (err) {
console.error('键盘设备连接失败:', err);
}
}
// 监听键盘输入报告
async function connectKeyboard(device) {
try {
await device.open();
console.log('键盘设备已打开');
// 监听输入报告
device.addEventListener('inputreport', (event) => {
const { reportId, data } = event;
const keyData = new Uint8Array(data.buffer);
console.log(`键盘报告ID: ${reportId}`);
console.log('键盘按键信息:', keyData);
// 处理按键数据(如处理扫描码)
handleKeyPress(keyData);
});
} catch (err) {
console.error('键盘设备连接失败:', err);
}
}
// 处理按键按下的事件
function handleKeyPress(keyData) {
// 假设第一个字节存储的是按键状态
const pressedKey = keyData[0]; // 这里可以是按键的扫描码
console.log('按下的键:', pressedKey);
}
2. 鼠标设备数据读取
与键盘类似,鼠标设备也通过输入报告来传输数据。鼠标设备通常会提供位置信息、按键状态等数据。通过 inputreport 事件,我们可以获取这些信息,从而实现鼠标操作的响应。
获取鼠标设备数据的代码示例:
javascript
async function requestMouseDevice() {
try {
const device = await navigator.hid.requestDevice({
filters: [{ usagePage: 0x01, usage: 0x02 }] // 匹配鼠标设备
});
console.log('鼠标设备已连接:', device);
return device;
} catch (err) {
console.error('鼠标设备连接失败:', err);
}
}
// 监听鼠标输入报告
async function connectMouse(device) {
try {
await device.open();
console.log('鼠标设备已打开');
// 监听输入报告
device.addEventListener('inputreport', (event) => {
const { reportId, data } = event;
const mouseData = new Uint8Array(data.buffer);
console.log(`鼠标报告ID: ${reportId}`);
console.log('鼠标数据:', mouseData);
// 处理鼠标数据(如鼠标移动、按键状态)
handleMouseMovement(mouseData);
});
} catch (err) {
console.error('鼠标设备连接失败:', err);
}
}
// 处理鼠标数据(如按键、坐标)
function handleMouseMovement(mouseData) {
const buttonState = mouseData[0]; // 按键状态(如左键、右键)
const xMovement = mouseData[1]; // X 轴移动
const yMovement = mouseData[2]; // Y 轴移动
console.log(`鼠标按键状态: ${buttonState}`);
console.log(`鼠标X轴移动: ${xMovement}, Y轴移动: ${yMovement}`);
}
六、兼容性
WebHID API是一个 Web 平台的实验性 API,并不是 W3C 标准。它是由Web平台孵化社区组(WICG - 非正式的组织,旨在为 Web 标准的实验性提案提供一个讨论平台)发布的规范。目前用于在Web应用中与外部硬件设备(如键盘、鼠标、游戏控制器等)进行交互。它允许浏览器直接访问这些设备,提供了与硬件设备通信的能力。虽然其在浏览器端提供了极大的便利,但在不同浏览器和平台上的支持度仍然存在差异。目前 WebHID 的兼容性主要集中在以下几个方面:
1. 浏览器支持
- Chrome:WebHID 已在 Google Chrome(v89 及更高版本)中实现,并且支持 Windows、macOS、Linux 和 Chrome OS。
- Edge:微软 Edge 也支持 WebHID,但同样需要较新的版本(基于 Chromium 内核的版本)。
- Firefox:目前 Firefox 不支持 WebHID API。
- Safari:Safari 浏览器目前也不原生支持 WebHID,但可以通过 WebKit 的某些实验性功能启用(需要用户手动设置)。
2. 操作系统支持
- Windows:Windows 系统上,WebHID 对 USB 和蓝牙 HID 设备的支持比较完善,尤其是在 Chrome 和 Edge 浏览器中。
- macOS:macOS 也对 WebHID 提供了良好的支持,尤其是在 Chrome 浏览器中。
- Linux:Linux 上对 WebHID 的支持较好,但可能会在不同的发行版上有所不同。
3. 移动设备支持
- Android:Android 上的 Chrome 浏览器已开始支持 WebHID,但并非所有设备都支持。
- iOS:iOS 对 WebHID 的支持非常有限,Safari 和其他浏览器不支持 WebHID。
4. 安全性
由于 WebHID 涉及到直接与硬件设备的交互,因此它被认为是一种潜在的安全风险。在访问 HID 设备时,浏览器会要求用户明确授权,并且 WebHID 的功能通常只能在 HTTPS 环境下使用,以确保数据传输的安全。
七、总结
WebHID API 为 Web 开发者提供了与硬件设备直接交互的能力,使得 Web 应用能够访问并控制 USB 或蓝牙的 HID 设备,如键盘、鼠标、游戏手柄等。通过 WebHID,开发者不再需要外部插件或原生应用的支持,可以直接通过浏览器进行硬件交互,极大地扩展了 Web 应用的功能。
主要收获:
-
与硬件设备的直接通信:WebHID API 使开发者能够直接与硬件设备进行交互,获取实时的数据更新,如鼠标的移动、键盘的按键输入等。与传统的客户端开发方式相比,WebHID 提供了更为便捷的 Web 端硬件支持。
-
多种 HID 设备支持:目前,WebHID API 已经支持键盘、鼠标、游戏手柄等设备,未来可能会支持更多设备,如打印机、扫描仪等,进一步拓展 Web 应用的应用场景。
-
简单易用:WebHID API 基于标准的 Web 技术(JavaScript),并通过浏览器提供支持,开发者可以轻松地集成到现有的 Web 应用中,而无需依赖额外的驱动程序或复杂的本地软件。
-
实时数据传输与控制:通过输入报告和输出报告机制,Web 应用可以实时获取设备的状态数据,甚至向设备发送控制指令,进一步增强用户交互体验。
应用场景:
游戏开发:通过与游戏手柄或其他输入设备的交互,可以实现更精细的游戏控制,提升用户体验。工业控制与监测:在工业领域中,WebHID 可用于与专用设备进行数据交互,实现远程监控与控制。物理设备模拟:如虚拟化硬件设备,进行模拟控制和数据同步。可穿戴设备:WebHID 可以应用于智能手表、健身追踪器等可穿戴设备的控制和数据获取。
持续发展的可能性:
WebHID 作为一项新兴技术,其功能和支持的设备类型正在不断扩展。未来,随着标准的完善和浏览器的广泛支持,WebHID 可能会成为 Web 开发中与硬件设备交互的标准接口,进一步丰富 Web 应用的功能和交互能力。
作者: 王新焱
博客: https://blog.csdn.net/qq_34402069
时间: 2025年12月16日