Signatur
Beschreibung
Die Methode requestPort() der Schnittstelle Serial (erreichbar über navigator.serial) öffnet einen vom Browser gesteuerten Auswahldialog. Darin sieht der Benutzer die angeschlossenen seriellen Geräte, zum Beispiel USB-Seriell-Wandler, Arduino-Boards, Mikrocontroller oder Bluetooth-Geräte mit RFCOMM. Wählt der Benutzer ein Gerät aus, erfüllt sich das Promise mit einem SerialPort-Objekt. Gleichzeitig erhält die Webseite dauerhaft die Berechtigung für dieses Gerät.
Über das Objekt options lässt sich die Liste im Dialog mit filters einschränken. Das geht über die USB-Hersteller-ID (usbVendorId) und die Produkt-ID (usbProductId) oder bei Bluetooth über die Dienst-Klassen-ID (bluetoothServiceClassId). So bekommt der Benutzer nur Geräte zu sehen, die zu Ihrer Anwendung passen.
Wichtig: Die Methode braucht eine vorübergehende Benutzeraktivierung (transient user activation). Sie muss also direkt in einem Handler für eine Benutzeraktion wie click aufgerufen werden. Nach der Auswahl öffnen Sie den Port mit SerialPort.open() und lesen oder schreiben dann über port.readable bzw. port.writable. Ports, für die bereits eine Berechtigung besteht, liefert Serial.getPorts() auch ohne neuen Dialog.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $options | Object | {} | Optionales Konfigurationsobjekt für den Auswahldialog. |
| $options.filters | Array<{usbVendorId?: number, usbProductId?: number, bluetoothServiceClassId?: number|string}> | [] | Liste von Filtern. Im Dialog erscheinen nur Geräte, auf die mindestens ein Filter passt. usbProductId darf nur zusammen mit usbVendorId angegeben werden. |
| $options.allowedBluetoothServiceClassIds | Array<number|string> | [] | Liste von Bluetooth-Dienst-Klassen-IDs (UUIDs oder 16/32-Bit-Aliase), die zusätzlich zum Standard-Seriell-Profil erlaubt sind (Chrome 130+). |
Rückgabewert
SerialPort erfüllt. Es wird mit NotFoundError abgelehnt, wenn der Benutzer den Dialog abbricht oder kein passendes Gerät vorhanden ist, und mit SecurityError, wenn keine Benutzeraktivierung vorliegt oder eine Permissions-Policy den Zugriff sperrt.Beispiele
Port per Klick auswählen und öffnen
const button = document.querySelector('#verbinden');
button.addEventListener('click', async () => {
if (!('serial' in navigator)) {
console.warn('Web Serial API wird nicht unterstützt.');
return;
}
try {
const port = await navigator.serial.requestPort();
await port.open({ baudRate: 9600 });
console.log('Verbunden:', port.getInfo());
} catch (err) {
if (err.name === 'NotFoundError') {
console.log('Kein Gerät ausgewählt.');
} else {
console.error('Fehler:', err);
}
}
});
Auswahl auf Arduino-Boards filtern
const ARDUINO_VENDOR_ID = 0x2341;
document.querySelector('#arduino').addEventListener('click', async () => {
const port = await navigator.serial.requestPort({
filters: [
{ usbVendorId: ARDUINO_VENDOR_ID, usbProductId: 0x0043 }, // Uno
{ usbVendorId: ARDUINO_VENDOR_ID, usbProductId: 0x0042 } // Mega 2560
]
});
const { usbVendorId, usbProductId } = port.getInfo();
console.log(`Gewählt: ${usbVendorId.toString(16)}:${usbProductId.toString(16)}`);
});
Daten lesen nach der Auswahl
document.querySelector('#lesen').addEventListener('click', async () => {
const port = await navigator.serial.requestPort();
await port.open({ baudRate: 115200 });
const decoder = new TextDecoderStream();
port.readable.pipeTo(decoder.writable);
const reader = decoder.readable.getReader();
try {
while (true) {
const { value, done } = await reader.read();
if (done) break;
console.log('Empfangen:', value);
}
} finally {
reader.releaseLock();
}
});
Bereits erlaubte Ports wiederverwenden
const getPort = async () => {
// Zuerst prüfen, ob schon eine Berechtigung besteht
const ports = await navigator.serial.getPorts();
if (ports.length > 0) return ports[0];
// Sonst Dialog anzeigen (nur im Klick-Handler erlaubt)
return navigator.serial.requestPort();
};
document.querySelector('#start').addEventListener('click', async () => {
const port = await getPort();
console.log('Port bereit:', port.getInfo());
});
// Wichtig · Fallstricke
- Browser-Unterstützung: Nur Chromium-basierte Desktop-Browser (Chrome, Edge, Opera). Firefox und Safari unterstützen die API nicht. Unter Android gibt es sie erst ab Chrome 138 und nur eingeschränkt. Prüfen Sie die Verfügbarkeit immer mit
'serial' in navigator. - Sicherer Kontext: Die API steht nur über HTTPS oder
localhostzur Verfügung. - Benutzeraktivierung: Ohne direkte Benutzeraktion (z. B. Klick) wird das Promise mit
SecurityErrorabgelehnt. Ein Aufruf beim Laden der Seite oder nach einem langenawaitfunktioniert daher nicht. - Permissions-Policy: In iframes muss die Direktive
serialerlaubt sein, z. B.<iframe allow="serial">. Sonst schlägt der Aufruf fehl. - Abbruch durch den Benutzer: Schließt der Benutzer den Dialog, wird das Promise mit
NotFoundErrorabgelehnt. Fangen Sie diesen Fall gezielt ab, statt ihn als Fehler zu melden. - Ein ausgewählter Port ist noch nicht geöffnet. Rufen Sie danach
port.open({ baudRate })auf. Ein Port kann nur einmal gleichzeitig geöffnet sein, auch über mehrere Tabs hinweg. - Eine erteilte Berechtigung lässt sich mit
SerialPort.forget()wieder entziehen.