Signatur
Beschreibung
Mit claimInterface() übernimmt eine Web-Anwendung die exklusive Kontrolle über ein bestimmtes Interface eines USB-Geräts. Erst danach kann sie Datenübertragungen über die Endpunkte dieses Interfaces ausführen, etwa mit transferIn(), transferOut() oder isochronen Übertragungen. Auch Control-Transfers mit dem Empfänger "interface" oder "endpoint" setzen ein beanspruchtes Interface voraus.
Die übliche Reihenfolge sieht so aus: Mit navigator.usb.requestDevice() das Gerät auswählen, mit device.open() eine Sitzung öffnen, bei Bedarf mit selectConfiguration() eine Konfiguration wählen und anschließend claimInterface() aufrufen. Die Interface-Nummer steht in device.configuration.interfaces[i].interfaceNumber.
Ist die Übernahme erfolgreich, steht die Eigenschaft claimed des passenden USBInterface-Objekts auf true. Wenn Sie das Interface nicht mehr brauchen, geben Sie es mit releaseInterface() wieder frei. Beim Aufruf von close() werden alle Interfaces automatisch freigegeben.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $interfaceNumber Pflicht | number | Die Nummer des Interfaces (bInterfaceNumber) in der aktiven Konfiguration, das beansprucht werden soll. |
Rückgabewert
Promise, das ohne Wert erfüllt wird, sobald das Interface beansprucht ist. Es wird mit einer DOMException abgelehnt, wenn das Gerät nicht geöffnet ist (InvalidStateError), die Interface-Nummer nicht existiert (NotFoundError), der Zugriff blockiert ist (SecurityError) oder das Betriebssystem bzw. ein anderer Treiber das Interface belegt (NetworkError).Beispiele
Gerät öffnen und Interface 0 beanspruchen
const connect = async () => {
// Gerät auswählen (muss durch eine Nutzeraktion ausgelöst werden)
const device = await navigator.usb.requestDevice({
filters: [{ vendorId: 0x2341 }]
});
await device.open();
if (device.configuration === null) {
await device.selectConfiguration(1);
}
await device.claimInterface(0);
console.log('Interface beansprucht:', device.configuration.interfaces[0].claimed);
return device;
};
document.querySelector('#connect').addEventListener('click', connect);
Passendes Interface anhand der Klasse suchen (herstellerspezifisch, 0xFF)
const claimVendorInterface = async (device) => {
const iface = device.configuration.interfaces.find((i) =>
i.alternates.some((alt) => alt.interfaceClass === 0xff)
);
if (!iface) throw new Error('Kein herstellerspezifisches Interface gefunden');
await device.claimInterface(iface.interfaceNumber);
console.log(`Interface ${iface.interfaceNumber} gehört jetzt uns`);
return iface.interfaceNumber;
};
Fehler behandeln, Daten senden und Interface wieder freigeben
const sendCommand = async (device, ifaceNumber, endpoint, bytes) => {
try {
await device.claimInterface(ifaceNumber);
} catch (err) {
if (err.name === 'NetworkError') {
console.error('Interface ist von einem anderen Treiber belegt.');
} else {
console.error('Übernahme fehlgeschlagen:', err.name, err.message);
}
return;
}
try {
const result = await device.transferOut(endpoint, new Uint8Array(bytes));
console.log('Status:', result.status, '– gesendet:', result.bytesWritten);
} finally {
await device.releaseInterface(ifaceNumber);
}
};
// Wichtig · Fallstricke
- Browser-Unterstützung: WebUSB gibt es nur in Chromium-basierten Browsern (Chrome, Edge, Opera). Firefox und Safari unterstützen die API nicht. Prüfen Sie vorher mit
'usb' in navigator, ob sie vorhanden ist. - Sicherer Kontext: Die API funktioniert nur über HTTPS (oder
localhost). In Cross-Origin-iframes ist sie nur verfügbar, wenn die Permissions Policyusbsie freigibt. - Vom Betriebssystem belegte Interfaces: Interfaces, die schon ein Treiber des Betriebssystems nutzt, lassen sich meist nicht beanspruchen. Das betrifft vor allem HID, Massenspeicher und unter Windows oft CDC-ACM. Die Folge ist ein
NetworkError. Unter Windows braucht das Gerät häufig einen WinUSB-Treiber. Für HID-Geräte eignet sich die WebHID-API besser. - Geschützte Klassen: Chrome sperrt bestimmte Interface-Klassen wie Audio, Video, HID, Massenspeicher und Smartcard. Der Aufruf endet dann mit einem
SecurityError. - Das Gerät muss vorher mit
open()geöffnet sein. Sonst gibt es einenInvalidStateError. - Die Exklusivität gilt auch zwischen Tabs: Hat ein anderer Tab oder ein anderes Programm das Interface schon beansprucht, schlägt der Aufruf fehl.
- Nach
selectConfiguration()mit einer anderen Konfiguration verlieren Sie alle beanspruchten Interfaces und müssen sie neu beanspruchen.