Signatur
Beschreibung
HIDDevice steht für ein einzelnes HID-Gerät wie einen Gamecontroller, ein Makro-Keypad, einen Barcode-Scanner, ein Stream Deck oder eine Spezialtastatur. Eine Instanz legst du nicht selbst an. Du bekommst sie von navigator.hid.requestDevice() (Auswahldialog, braucht eine Nutzeraktion), von navigator.hid.getDevices() (Geräte, die bereits freigegeben wurden) oder über die Events connect/disconnect von navigator.hid.
Wichtige Eigenschaften (nur lesbar):
opened:boolean, ob eine Verbindung zum Gerät offen ist.vendorId/productId: USB-Hersteller- bzw. Produktkennung als Zahl.productName: Produktname als Zeichenkette.collections: Array vonHIDCollectionInfo-Objekten, die das Report-Format beschreiben (Usage Page, Usage, Input-/Output-/Feature-Reports).
Wichtige Methoden, alle geben ein Promise zurück:
open()/close(): Verbindung öffnen bzw. schließen.forget(): Gibt die erteilte Berechtigung wieder ab.sendReport(reportId, data): Sendet einen Output-Report.sendFeatureReport(reportId, data): Sendet einen Feature-Report.receiveFeatureReport(reportId): Liest einen Feature-Report und löst mit einemDataViewauf.
Eingehende Daten kommen über das Event inputreport an. Du registrierst es mit device.addEventListener("inputreport", handler) oder über device.oninputreport. Das Event-Objekt (HIDInputReportEvent) enthält reportId, data (ein DataView) und device.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $reportId Pflicht | number | Für sendReport(), sendFeatureReport() und receiveFeatureReport(): 8-Bit-Report-ID. Benutzt das Gerät keine Report-IDs, übergibst du 0. |
|
| $data Pflicht | BufferSource (ArrayBuffer | TypedArray | DataView) | Für sendReport() und sendFeatureReport(): die Nutzdaten des Reports ohne die Report-ID. |
Rückgabewert
navigator.hid.requestDevice() bzw. getDevices() als Array geliefert, also Promise<HIDDevice[]>. Die Methoden der Instanz geben Promise<void> zurück, receiveFeatureReport() dagegen Promise<DataView>.Beispiele
Gerät auswählen und öffnen
// Muss in einem Klick-Handler laufen (Nutzeraktion nötig)
const button = document.querySelector('#connect');
button.addEventListener('click', async () => {
if (!('hid' in navigator)) {
console.warn('WebHID wird nicht unterstützt');
return;
}
// Filter: z. B. Geräte von Sony (Vendor-ID 0x054c)
const [device] = await navigator.hid.requestDevice({
filters: [{ vendorId: 0x054c }]
});
if (!device) return; // Dialog abgebrochen
if (!device.opened) await device.open();
console.log(`Verbunden: ${device.productName}`,
device.vendorId.toString(16), device.productId.toString(16));
});
Input-Reports empfangen und Listener wieder entfernen
const handleReport = (event) => {
const { data, reportId, device } = event;
// Erstes Byte auslesen, z. B. Tastenstatus
const buttons = data.getUint8(0);
console.log(`${device.productName} – Report ${reportId}: ${buttons.toString(2)}`);
};
const [device] = await navigator.hid.getDevices();
if (device) {
await device.open();
device.addEventListener('inputreport', handleReport);
// Nach 10 Sekunden aufräumen
setTimeout(async () => {
device.removeEventListener('inputreport', handleReport);
await device.close();
}, 10_000);
}
Output- und Feature-Reports senden bzw. lesen
const [device] = await navigator.hid.getDevices();
await device.open();
// Output-Report: LED-Farbe setzen (gerätespezifisches Format!)
const reportId = 0x05;
const payload = new Uint8Array([0xff, 0x00, 0x80]); // RGB
await device.sendReport(reportId, payload);
// Feature-Report lesen, z. B. Firmware-Version
const view = await device.receiveFeatureReport(0x02);
console.log('Firmware-Byte:', view.getUint8(1));
Report-Struktur untersuchen und Berechtigung widerrufen
const [device] = await navigator.hid.getDevices();
for (const col of device.collections) {
console.log(`Usage-Page 0x${col.usagePage.toString(16)}, Usage 0x${col.usage.toString(16)}`);
col.inputReports.forEach((r) => console.log(' Input-Report-ID:', r.reportId));
}
// Zugriff wieder abgeben (Chrome 100+)
await device.forget();
// Wichtig · Fallstricke
- Browser-Unterstützung: Die API ist experimentell und nur in Chromium-Browsern auf dem Desktop verfügbar (Chrome/Edge 89+). Firefox und Safari unterstützen sie nicht, Android ebenfalls nicht. Prüfe vorher mit
'hid' in navigator, ob sie vorhanden ist. - Sicherer Kontext: Die API läuft nur über HTTPS oder
localhost.requestDevice()braucht eine Nutzeraktion, z. B. einen Klick. In iframes muss die Permissions Policyhiderlaubt sein. In Workern gibt es die API nur in Extension-Service-Workern. - Gesperrte Geräte: Tastaturen, Mäuse und sicherheitsrelevante Geräte wie FIDO-/U2F-Sicherheitsschlüssel werden per Blockliste ausgefiltert oder nur eingeschränkt freigegeben. Sonst ließen sich damit z. B. Eingaben mitschneiden.
- Das Report-Format hängt vom Gerät ab. Ohne Kenntnis des HID-Report-Deskriptors bzw. der Herstellerdoku kannst du die Bytes nicht sinnvoll deuten.
sendReport()wird abgelehnt, wenn das Gerät nicht geöffnet ist (InvalidStateError) oder die Übertragung fehlschlägt (NotAllowedError). Verwende deshalb immertry/catch.- Bei
datagibst du die Report-ID nicht mit an, sie wird separat übergeben. - Wird das Gerät abgesteckt, feuert
navigator.hiddas Eventdisconnect. Danach ist die Instanz nicht mehr nutzbar.