Signatur
Beschreibung
USBDevice ist das zentrale Objekt der WebUSB API. Eine Instanz steht für ein physisches USB-Gerät, für das der Nutzer der Seite den Zugriff erlaubt hat. Man erzeugt sie nicht selbst, sondern bekommt sie von navigator.usb.requestDevice() (Auswahldialog), navigator.usb.getDevices() (bereits freigegebene Geräte) oder über die Ereignisse connect/disconnect von navigator.usb.
Die schreibgeschützten Eigenschaften beschreiben das Gerät: vendorId, productId, deviceClass, deviceSubclass, deviceProtocol, manufacturerName, productName, serialNumber, die Versionsangaben usbVersionMajor/Minor/Subminor und deviceVersionMajor/Minor/Subminor sowie configuration, configurations und opened.
Die Methoden geben alle ein Promise zurück. Der übliche Ablauf ist open(), dann selectConfiguration(), dann claimInterface(). Danach überträgt man Daten mit transferIn()/transferOut() (Bulk/Interrupt), controlTransferIn()/controlTransferOut() (Steuerübertragungen) oder isochronousTransferIn()/isochronousTransferOut(). Weitere Methoden sind selectAlternateInterface(), clearHalt(), reset(), releaseInterface(), close() und forget().
Gedacht ist WebUSB für eigene oder herstellerspezifische Hardware wie Mikrocontroller, Messgeräte oder Programmieradapter, für die es keine passende höherwertige API gibt. Für Tastaturen, Gamepads, serielle Adapter oder Speichermedien sind WebHID, die Gamepad API, Web Serial oder das Betriebssystem zuständig.
Rückgabewert
navigator.usb.requestDevice(), navigator.usb.getDevices() oder über USBConnectionEvent.device. Einen öffentlichen Konstruktor gibt es nicht.Beispiele
Gerät anfordern und Metadaten auslesen
// Muss in einer Nutzeraktion (z. B. Klick) aufgerufen werden
const button = document.querySelector('#verbinden');
button.addEventListener('click', async () => {
try {
const device = await navigator.usb.requestDevice({
filters: [{ vendorId: 0x2341 }] // z. B. Arduino
});
console.log(device.productName, device.manufacturerName);
console.log('VID:', device.vendorId.toString(16), 'PID:', device.productId.toString(16));
console.log('Seriennummer:', device.serialNumber);
} catch (err) {
console.warn('Kein Gerät ausgewählt:', err.message);
}
});
Öffnen, Interface belegen und Daten senden/empfangen
const kommuniziere = async (device) => {
await device.open();
if (device.configuration === null) {
await device.selectConfiguration(1);
}
await device.claimInterface(0);
// Bulk-OUT an Endpunkt 1
const befehl = new TextEncoder().encode('PING\n');
const out = await device.transferOut(1, befehl);
console.log('Gesendet:', out.bytesWritten, 'Bytes');
// Bulk-IN von Endpunkt 2, max. 64 Bytes
const result = await device.transferIn(2, 64);
if (result.status === 'ok') {
console.log('Antwort:', new TextDecoder().decode(result.data));
}
await device.releaseInterface(0);
await device.close();
};
const [device] = await navigator.usb.getDevices();
if (device) await kommuniziere(device);
Herstellerspezifische Steuerübertragung
const setzeLed = async (device, an) => {
await device.controlTransferOut({
requestType: 'vendor',
recipient: 'device',
request: 0x01, // herstellerspezifischer Befehl
value: an ? 1 : 0,
index: 0
});
};
const leseStatus = async (device) => {
const res = await device.controlTransferIn({
requestType: 'vendor',
recipient: 'device',
request: 0x02,
value: 0,
index: 0
}, 1);
return res.data.getUint8(0);
};
const [device] = await navigator.usb.getDevices();
await device.open();
await setzeLed(device, true);
console.log('Status:', await leseStatus(device));
Verbindungswechsel überwachen und Freigabe widerrufen
navigator.usb.addEventListener('connect', ({ device }) => {
console.log('Angeschlossen:', device.productName);
});
navigator.usb.addEventListener('disconnect', ({ device }) => {
console.log('Getrennt:', device.productName, '– geöffnet?', device.opened);
});
// Freigabe dauerhaft widerrufen (Chrome 101+)
const [device] = await navigator.usb.getDevices();
await device?.forget();
// Wichtig · Fallstricke
- Kompatibilität: Nur in Chromium-Browsern (Chrome, Edge, Opera) auf Desktop und Android. Firefox und Safari unterstützen WebUSB nicht. Vor der Nutzung mit
'usb' in navigatorprüfen. - Sicherer Kontext: Funktioniert nur über HTTPS oder
localhost.requestDevice()braucht eine Nutzeraktion. In iframes muss die Permissions-Policyusbden Zugriff erlauben. - Geschützte Geräteklassen: Der Browser sperrt Interfaces der Klassen HID, Massenspeicher, Audio, Video, Smartcard und Drucker. Ein
claimInterface()darauf schlägt mitSecurityErrorfehl. - Betriebssystem-Treiber: Hat das Betriebssystem das Interface schon belegt (unter Windows oft ein Hersteller-Treiber statt WinUSB, unter Linux etwa
cdc_acm), meldetclaimInterface()einenNetworkError. Unter Linux fehlen häufig udev-Regeln für die Zugriffsrechte. - Endpunkt-Nummern werden ohne Richtungsbit angegeben (
1statt0x81). Die Richtung ergibt sich austransferInbzw.transferOut. - Den Status des Ergebnisses immer prüfen: Bei
'stall'den Endpunkt mitclearHalt()zurücksetzen, bei'babble'hat das Gerät mehr Daten geschickt als angefordert. - Sicherheit: Direkter Hardwarezugriff kann Firmware verändern. Nur vertrauenswürdige Seiten sollten die Freigabe bekommen. Mit
forget()lässt sich die Freigabe wieder entziehen.