如何基于 WebHID 或 WebUSB 实现网页与工业级硬件的底层数据交互需要先看清适用场景和关键步骤,避免只记结论却忽略实际限制。
WebHID是工业硬件网页接入的现实可行路径,因工业设备只需符合HID协议(如STM32/ESP32自定义HID描述符)即可被发现,而WebUSB依赖厂商预置签名webusb.json,生态缺失导致其在工业现场几乎不可用。
WebHID 和 WebUSB 都能实现网页与硬件通信,但工业级场景下 WebHID 更可靠、更易部署;WebUSB 在多数工业设备上根本不可用——因为需要厂商主动声明 USB 接口支持 WebUSB(即提供 webusb.json 并签名),而绝大多数 PLC、传感器网关、工控模块压根没做这事。
工业设备只要符合 HID 协议(哪怕只是模拟成一个“自定义 HID 类设备”),就能被 navigator.hid.requestDevice() 发现。很多嵌入式方案(如 STM32 + TinyUSB、ESP32-S3 + ESP-IDF HID stack)已稳定支持 HID 报告描述符自定义,无需改硬件接口形态。
bInterfaceClass = 0x03 和 bInterfaceSubClass = 0x00(无启动子类)requestDevice({ filters: [...] }),filter 中至少指定 vendorId 和 productId,避免弹窗列出所有 HID 设备requestDevice
device.addEventListener('inputreport', ...),发送用 device.sendReport(reportId, data);注意 reportId 必须与 descriptor 中定义一致不是技术不行,而是生态断层:WebUSB 要求设备在 USB 描述符中嵌入一个指向 webusb.json 的 URL,并由有效证书签名。现实中,西门子、研华、MOXA 等厂商的 USB 工控模块均未启用该机制;即使你自研设备,Chrome 对自签名证书的拦截越来越严格,chrome://flags/#unsafely-treat-insecure-origin-as-secure 已被移除。
SecurityError: Access denied 或 NotFoundError: No device selected —— 很可能根本没进设备选择弹窗,因为 USB 描述符里缺 WebUSB Platform Capability Descriptor
usbConnection 事件不会触发,navigator.usb.getDevices() 返回空数组,即使设备已插入且系统识别正常--unsafely-disable-dev-certificate-validation),也无法通过 Chrome Web Store 审核,生产环境不可行别把 HID 当成裸串口封装。工业数据常含状态字、CRC、多通道采样值,直接塞进 64 字节 report 容易出错。推荐用固定 report layout + 应用层解析,而非依赖 HID 的“feature/input/output report 自动分片”。
inputreport 事件延迟或合并;可在 firmware 中加 usage page 和 usage 显式区分功能域,减少系统干预浏览器不管理 HID 设备生命周期。用户拔插、休眠唤醒、页面刷新都会中断连接,且 device.onconnect/ondisconnect 并不可靠(Chrome 有时不触发)。不能依赖自动重连。
hidconnectionavailable 事件仅作提示,实际要用定时轮询 navigator.hid.getDevices() + device.open() 尝试恢复sendReport 前检查 device.opened === true,失败则先 await device.open();注意 open() 是异步且可能被拒绝(如设备正被其他进程占用)AbortController 控制 sendReport,3 秒无 inputreport 回应则标记失败真正卡住项目的往往不是协议本身,而是 HID descriptor 的字段对齐方式、Windows 驱动对 report size 的隐式截断、以及 Chrome 对非标准 usage page 的静默忽略——这些细节不会出现在 MDN 文档里,只能靠 Wireshark + USBPcap 抓包比对 firmware 实际发出的 report 与 JS 接收是否一致。