Signatur
Beschreibung
Mit receiveFeatureReport() fragt eine Webanwendung über die WebHID API aktiv einen Feature Report von einem HID-Gerät ab (z. B. Tastatur, Gamepad, Messgerät, LED-Controller). Anders als Eingabeberichte, die das Gerät von selbst sendet und die über das Ereignis inputreport ankommen, werden Feature-Berichte auf Anfrage gelesen. Typischerweise stehen darin Konfigurationswerte, Firmware-Version, Akkustand oder Kalibrierungsdaten.
Die Methode gibt ein Promise zurück, das mit einem DataView erfüllt wird. Hat das Gerät nummerierte Berichte (Report-IDs ungleich 0), ist das erste Byte die Report-ID, danach folgen die Nutzdaten. Welche Report-IDs und Feldlayouts existieren, beschreibt der HID-Report-Deskriptor; über device.collections und dort featureReports lässt er sich auslesen.
Voraussetzung: Das Gerät wurde vorher per navigator.hid.requestDevice() vom Nutzer freigegeben (bzw. über navigator.hid.getDevices() wieder abgerufen) und mit device.open() geöffnet. Gegenstück zum Schreiben ist sendFeatureReport().
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $reportId Pflicht | number | 8-Bit-Report-ID (0–255) des gewünschten Feature-Berichts. Nutzt das Gerät keine Report-IDs, wird 0 übergeben. |
Rückgabewert
Promise, das mit einem DataView über die empfangenen Bytes erfüllt wird. Es wird abgelehnt (z. B. NotAllowedError oder InvalidStateError), wenn das Gerät nicht geöffnet ist, der Bericht nicht existiert oder das Lesen fehlschlägt.Beispiele
Gerät auswählen, öffnen und Feature-Bericht lesen
// Muss durch eine Nutzergeste (z. B. Klick) ausgelöst werden
document.querySelector('#verbinden').addEventListener('click', async () => {
const [device] = await navigator.hid.requestDevice({
filters: [{ vendorId: 0x046d }] // Beispiel: Logitech
});
if (!device) return;
if (!device.opened) await device.open();
const view = await device.receiveFeatureReport(1);
const bytes = new Uint8Array(view.buffer, view.byteOffset, view.byteLength);
console.log('Report-ID:', bytes[0]);
console.log('Daten:', [...bytes.slice(1)].map(b => b.toString(16).padStart(2, '0')).join(' '));
});
Firmware-Version und Akkustand auswerten
const leseStatus = async (device) => {
try {
const view = await device.receiveFeatureReport(0x05);
// Layout laut Hersteller: [ID, Major, Minor, Akku %]
const major = view.getUint8(1);
const minor = view.getUint8(2);
const akku = view.getUint8(3);
return { firmware: `${major}.${minor}`, akku };
} catch (err) {
console.error('Feature-Bericht nicht lesbar:', err.name, err.message);
return null;
}
};
const [device] = await navigator.hid.getDevices();
if (device) {
await device.open();
console.log(await leseStatus(device));
}
Verfügbare Feature-Report-IDs aus dem Deskriptor ermitteln
const featureIds = (device) =>
device.collections.flatMap(c => c.featureReports.map(r => r.reportId));
const [device] = await navigator.hid.getDevices();
await device.open();
for (const id of featureIds(device)) {
const view = await device.receiveFeatureReport(id);
console.log(`Report ${id}: ${view.byteLength} Bytes`);
}
// Wichtig · Fallstricke
- Browser-Unterstützung: Nur Chromium-basierte Desktop-Browser (Chrome/Edge/Opera ab Version 89). Firefox und Safari unterstützen WebHID nicht; vorher mit
'hid' in navigatorprüfen. - Sicherer Kontext: Nur über HTTPS (oder
localhost) verfügbar; in iframes ist die Permissions-Policyhidnötig. Die Geräteauswahl erfordert eine Nutzergeste. - Gerät muss geöffnet sein: Ohne vorheriges
await device.open()wird das Promise mitInvalidStateErrorabgelehnt. - Report-ID im Ergebnis: Das erste Byte des
DataViewenthält bei nummerierten Berichten die Report-ID – Offsets beim Parsen entsprechend um 1 verschieben. Das Verhalten kann sich je nach Betriebssystem leicht unterscheiden; immerbyteLengthprüfen. - Blockierte Geräte: Sicherheitskritische Geräteklassen (z. B. FIDO-Sicherheitsschlüssel) und manche Tastatur-/Maus-Collections sind vom Browser gesperrt und nicht lesbar.
- Nebenläufige Aufrufe auf dasselbe Gerät möglichst serialisieren (nacheinander
awaiten), da manche Geräte parallele Anfragen schlecht vertragen.