Signatur
Beschreibung
Mit sendFeatureReport() schickt man über die WebHID API einen Feature-Report an ein HID-Gerät (Human Interface Device). Feature-Reports dienen meist zur Konfiguration eines Geräts, etwa um die Hintergrundbeleuchtung einer Tastatur einzustellen, die DPI-Stufe einer Maus zu ändern, einen Gerätemodus umzuschalten oder Firmware-Parameter zu setzen. Im Unterschied zu Output-Reports (sendReport()), die laufend Daten übertragen, sind Feature-Reports für seltene Einstellungen gedacht und lassen sich auch mit receiveFeatureReport() zurücklesen.
Vor dem Aufruf muss das Gerät über navigator.hid.requestDevice() ausgewählt und mit device.open() geöffnet sein. Das zurückgegebene Promise wird erfüllt, sobald der Report gesendet wurde. Schlägt das Senden fehl, etwa weil das Gerät nicht geöffnet ist oder den Report ablehnt, wird es mit einer DOMException zurückgewiesen (meist InvalidStateError oder NotAllowedError).
Welche Report-IDs und welche Datenlänge ein Gerät erwartet, steht in seinem Report-Deskriptor. Ausgelesen wird er über device.collections und dort über die Eigenschaft featureReports. Verwendet das Gerät keine Report-IDs, übergibt man 0 als reportId. Die Report-ID wird nicht in data eingetragen, der Browser stellt sie selbst voran.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $reportId Pflicht | number | 8-Bit-Report-ID (0–255) des Feature-Reports. 0, wenn das Gerät keine Report-IDs verwendet. |
|
| $data Pflicht | BufferSource (ArrayBuffer | TypedArray | DataView) | Nutzdaten des Reports ohne vorangestellte Report-ID. Die Länge sollte der im Report-Deskriptor festgelegten Größe entsprechen. |
Rückgabewert
DOMException zurückgewiesen.Beispiele
Gerät auswählen, öffnen und Feature-Report senden
const connectBtn = document.querySelector('#connect');
connectBtn.addEventListener('click', async () => {
// Muss durch eine Nutzeraktion ausgelöst werden
const [device] = await navigator.hid.requestDevice({
filters: [{ vendorId: 0x046d }] // Beispiel: Logitech
});
if (!device) return;
if (!device.opened) await device.open();
// Report-ID 0x11, 3 Byte Nutzdaten
const data = new Uint8Array([0x01, 0x80, 0xff]);
try {
await device.sendFeatureReport(0x11, data);
console.log('Feature-Report gesendet');
} catch (err) {
console.error('Senden fehlgeschlagen:', err.name, err.message);
}
});
Tastaturbeleuchtung setzen und Ergebnis zurücklesen
const setBacklight = async (device, level) => {
const REPORT_ID = 0x05;
const payload = new Uint8Array(8); // Länge laut Report-Deskriptor
payload[0] = 0x02; // Befehl: Helligkeit
payload[1] = Math.min(255, Math.max(0, level));
await device.sendFeatureReport(REPORT_ID, payload);
// Kontrolle: denselben Feature-Report wieder abrufen
const view = await device.receiveFeatureReport(REPORT_ID);
// Byte 0 enthält beim Empfang die Report-ID
console.log('Aktuelle Helligkeit:', view.getUint8(2));
};
const [kbd] = await navigator.hid.getDevices();
if (kbd) {
await kbd.open();
await setBacklight(kbd, 128);
}
Erwartete Report-Größe aus dem Deskriptor ermitteln
const getFeatureReportSize = (device, reportId) => {
for (const collection of device.collections) {
const report = collection.featureReports.find(r => r.reportId === reportId);
if (report) {
// Summe aller Felder in Bit → Byte
const bits = report.items.reduce(
(sum, item) => sum + item.reportSize * item.reportCount, 0);
return Math.ceil(bits / 8);
}
}
return null;
};
const [device] = await navigator.hid.getDevices();
const size = getFeatureReportSize(device, 0x11);
if (size !== null) {
await device.open();
await device.sendFeatureReport(0x11, new Uint8Array(size));
console.log(`Report mit ${size} Byte gesendet`);
}
// Wichtig · Fallstricke
- Browser-Unterstützung: Nur Chromium-basierte Desktop-Browser (Chrome/Edge/Opera ab Version 89). Firefox und Safari unterstützen WebHID nicht. Vorher prüfen, ob
'hid' in navigatorgilt. - Sicherer Kontext: Funktioniert nur über HTTPS (oder
localhost). Außerdem muss die Permissions-Policyhiderlauben, was bei iframes relevant ist. - Gerät geöffnet? Ohne vorheriges
await device.open()wird das Promise mitInvalidStateErrorzurückgewiesen. - Report-ID nicht doppelt senden: Die ID gehört in den ersten Parameter, nicht in
data. Andernfalls verschieben sich alle Bytes um eine Stelle. Beim Empfang überreceiveFeatureReport()steht die ID dagegen in Byte 0 der Antwort. - Gesperrte Geräte: Chrome blockiert bestimmte Geräteklassen (z. B. Tastatur-Eingaben, FIDO-Sicherheitsschlüssel) und Top-Level-Collections, damit Tastenanschläge oder Anmeldedaten nicht abgegriffen werden können. Reports an solche Collections schlagen fehl.
- Vorsicht: Falsche Feature-Reports können Geräte fehlkonfigurieren. Deshalb nur Befehle senden, die in der Herstellerdokumentation beschrieben sind.
- Unter Windows müssen die Daten oft exakt die Länge aus dem Deskriptor haben, sonst schlägt der Aufruf fehl.