Start · Sprachen · JavaScript · Referenz · Navigator.serial

Navigator.serial

Eigenschaft

Schreibgeschützte Eigenschaft, die ein <code>Serial</code>-Objekt liefert – den Einstiegspunkt in die Web Serial API für den Zugriff auf serielle Geräte.

seit JavaScript Chromium 89+ (Chrome, Edge, Opera) – kein Firefox, Kategorie: webapi

Signatur

Navigator.serial

Beschreibung

Die schreibgeschützte Eigenschaft navigator.serial gibt ein Serial-Objekt zurück. Darüber können Webanwendungen mit seriellen Geräten kommunizieren, etwa mit Mikrocontrollern (Arduino, ESP32), 3D-Druckern, Messgeräten, Barcode-Scannern oder USB-Seriell-Adaptern. Dabei wird eine echte serielle Schnittstelle (RS-232) oder eine per USB/Bluetooth nachgebildete verwendet.

Das Serial-Objekt stellt vor allem zwei Methoden bereit: requestPort() öffnet einen Auswahldialog des Browsers, in dem der Nutzer ein Gerät freigibt. getPorts() liefert die Ports, die die Seite schon früher freigegeben bekommen hat. Zusätzlich meldet es mit den Events connect und disconnect, wenn ein freigegebenes Gerät angeschlossen oder abgezogen wird.

Die eigentliche Kommunikation läuft über SerialPort-Objekte. Nach port.open({ baudRate }) stehen port.readable und port.writable als ReadableStream bzw. WritableStream bereit. Die API funktioniert nur in einem sicheren Kontext (HTTPS oder localhost). requestPort() erfordert außerdem eine Nutzeraktion, zum Beispiel einen Klick.

Rückgabewert

Typ
Serial
Beschreibung
Das Serial-Objekt des aktuellen Dokuments. Es ist ein EventTarget mit den Methoden requestPort() und getPorts(). In Browsern ohne Unterstützung existiert die Eigenschaft nicht und liefert undefined.

Beispiele

Unterstützung prüfen

if ('serial' in navigator) {
  console.log('Web Serial API verfügbar');
} else {
  console.log('Web Serial API wird nicht unterstützt');
}
Web Serial API verfügbar

Port auswählen und Daten von einem Arduino lesen

// <button id="connect">Verbinden</button>
document.querySelector('#connect').addEventListener('click', async () => {
  try {
    // Nur Geräte mit Arduino-Hersteller-ID anzeigen
    const port = await navigator.serial.requestPort({
      filters: [{ usbVendorId: 0x2341 }]
    });
    await port.open({ baudRate: 9600 });

    const decoder = new TextDecoderStream();
    port.readable.pipeTo(decoder.writable);
    const reader = decoder.readable.getReader();

    while (true) {
      const { value, done } = await reader.read();
      if (done) break;
      console.log('Empfangen:', value);
    }
    reader.releaseLock();
  } catch (err) {
    console.error('Verbindung fehlgeschlagen:', err.name, err.message);
  }
});
Empfangen: Temperatur: 21.5

Freigegebene Ports wiederverwenden und Befehl senden

const sendCommand = async (text) => {
  const [port] = await navigator.serial.getPorts();
  if (!port) {
    console.log('Kein freigegebener Port – bitte zuerst verbinden.');
    return;
  }
  await port.open({ baudRate: 115200 });
  const writer = port.writable.getWriter();
  await writer.write(new TextEncoder().encode(text + '\n'));
  writer.releaseLock();
  await port.close();
  console.log('Gesendet:', text);
};

sendCommand('LED ON');
Gesendet: LED ON

Auf An- und Abstecken reagieren

navigator.serial.addEventListener('connect', (event) => {
  const { usbVendorId, usbProductId } = event.target.getInfo();
  console.log('Gerät verbunden:', usbVendorId, usbProductId);
});

navigator.serial.addEventListener('disconnect', (event) => {
  console.log('Gerät getrennt:', event.target.getInfo());
});
Gerät verbunden: 9025 67

// Wichtig · Fallstricke

  • Browser-Kompatibilität: Wird nur von Chromium-basierten Desktop-Browsern unterstützt (Chrome, Edge und Opera ab Version 89). Firefox und Safari unterstützen die API nicht. Auf Android ist die Unterstützung eingeschränkt. Prüfe die Unterstützung immer vorher mit 'serial' in navigator.
  • Sicherer Kontext: Die API steht nur über HTTPS oder auf localhost zur Verfügung. In Iframes muss die Permissions-Policy serial sie erlauben.
  • Nutzeraktion nötig: requestPort() ohne vorherigen Klick oder Tastendruck wirft einen SecurityError. Bricht der Nutzer den Dialog ab, folgt ein NotFoundError.
  • Port ist belegt: Nutzt ein anderes Programm oder ein anderer Tab den Port bereits, schlägt open() mit NetworkError bzw. InvalidStateError fehl.
  • Sauber schließen: Vor port.close() musst du alle Reader und Writer freigeben (releaseLock() bzw. reader.cancel()). Sonst wird der Port nicht geschlossen.
  • Baudrate: Sie muss mit der des Geräts übereinstimmen, sonst kommen unlesbare Daten an.
  • Sicherheit: Behandle Daten vom Gerät als nicht vertrauenswürdig und füge sie nie ungeprüft per innerHTML in die Seite ein.