Start · Sprachen · JavaScript · Referenz · new NDEFReader()

new NDEFReader()

Methode

Erzeugt ein neues <code>NDEFReader</code>-Objekt, mit dem sich NDEF-Nachrichten von NFC-Tags in Reichweite lesen und auf sie schreiben lassen.

seit JavaScript Experimentell: Chrome für Android 89+ (Web NFC), n Kategorie: webapi

Signatur

new NDEFReader()

Beschreibung

Der Konstruktor NDEFReader() ist der Einstieg in die Web NFC API. Das zurückgegebene Objekt stellt die Methoden scan(), write() und makeReadOnly() bereit und löst die Ereignisse reading und readingerror aus. So können Webanwendungen NFC-Tags im NDEF-Format (NFC Data Exchange Format) lesen und beschreiben, etwa für Inventarlisten, Eintrittskarten, Museumsführer oder zum Koppeln von Geräten.

Der Konstruktor hat keine Parameter und fragt selbst noch keine Berechtigung ab. Den Berechtigungsdialog zeigt der Browser erst beim ersten Aufruf von scan() oder write(), und dieser Aufruf muss durch eine Nutzeraktion ausgelöst werden, zum Beispiel durch einen Klick. In der Praxis erzeugt man den Reader deshalb meist in einem Klick-Handler oder hält eine Instanz bereit und startet den Scan erst nach einer Nutzereingabe.

NDEFReader erbt von EventTarget. Gelesene Nachrichten kommen als NDEFReadingEvent an, mit den Eigenschaften serialNumber und message (ein NDEFMessage mit einem Array aus NDEFRecord-Objekten). Einen laufenden Scan beendet man über ein AbortSignal, das man an scan() übergibt.

Rückgabewert

Typ
NDEFReader
Beschreibung
Ein neues NDEFReader-Objekt. Es scannt noch nicht und hat noch keine Berechtigung angefragt.

Beispiele

Feature-Erkennung und Instanziierung

if ('NDEFReader' in window) {
  const reader = new NDEFReader();
  console.log('Web NFC verfügbar:', reader instanceof EventTarget);
} else {
  console.log('Web NFC wird von diesem Browser nicht unterstützt.');
}
Web NFC verfügbar: true

Tags nach Klick scannen und Text-Records auslesen

const scanButton = document.querySelector('#scan');

scanButton.addEventListener('click', async () => {
  const reader = new NDEFReader();
  try {
    await reader.scan(); // löst den Berechtigungsdialog aus
    console.log('Scan gestartet – Tag an das Gerät halten.');

    reader.addEventListener('reading', ({ serialNumber, message }) => {
      console.log(`Tag erkannt: ${serialNumber}`);
      for (const record of message.records) {
        if (record.recordType === 'text') {
          const decoder = new TextDecoder(record.encoding ?? 'utf-8');
          console.log('Text:', decoder.decode(record.data));
        } else {
          console.log('Record-Typ:', record.recordType);
        }
      }
    });

    reader.addEventListener('readingerror', () => {
      console.warn('Tag konnte nicht gelesen werden (kein NDEF?).');
    });
  } catch (error) {
    console.error('Scan fehlgeschlagen:', error.name, error.message);
  }
});
Scan gestartet – Tag an das Gerät halten. Tag erkannt: 04:a2:3b:c1:5e:61:80 Text: Regal 12, Fach B

URL auf ein Tag schreiben

document.querySelector('#write').addEventListener('click', async () => {
  const writer = new NDEFReader();
  try {
    await writer.write({
      records: [{ recordType: 'url', data: 'https://programmierung.net' }]
    });
    console.log('URL erfolgreich auf das Tag geschrieben.');
  } catch (error) {
    console.error('Schreiben fehlgeschlagen:', error.message);
  }
});
URL erfolgreich auf das Tag geschrieben.

Scan mit AbortController zeitlich begrenzen

const startTimedScan = async (ms = 10000) => {
  const reader = new NDEFReader();
  const controller = new AbortController();

  reader.onreading = (event) => {
    console.log('Gelesen:', event.serialNumber);
    controller.abort(); // nach dem ersten Tag aufhören
  };

  controller.signal.addEventListener('abort', () => console.log('Scan beendet.'));
  setTimeout(() => controller.abort(), ms);

  await reader.scan({ signal: controller.signal });
};

document.querySelector('#scan').addEventListener('click', () => startTimedScan());
Gelesen: 04:a2:3b:c1:5e:61:80 Scan beendet.

// Wichtig · Fallstricke

  • Browser-Kompatibilität: Web NFC ist experimentell und wird nur von Chrome für Android (ab Version 89) und darauf aufbauenden Browsern unterstützt. Desktop-Browser, Firefox und Safari/iOS kennen NDEFReader nicht, daher immer vorher mit 'NDEFReader' in window prüfen.
  • Sicherer Kontext: Die API steht nur über HTTPS (oder localhost) und nur im Top-Level-Dokument zur Verfügung, nicht in eingebetteten iframes über fremde Origins.
  • Nutzeraktion erforderlich: Der Konstruktor läuft auch ohne Nutzeraktion, aber scan() und write() lehnen mit einem NotAllowedError ab, wenn keine Nutzeraktion vorausging oder der Nutzer die Berechtigung verweigert hat. Ist NFC am Gerät ausgeschaltet oder nicht vorhanden, gibt es einen NotReadableError bzw. NotSupportedError.
  • Sichtbarkeit: Gelesen wird nur, solange die Seite sichtbar ist und den Fokus hat. Im Hintergrund kommen keine reading-Ereignisse an.
  • Sicherheit: Tag-Inhalte sind nicht vertrauenswürdige Eingaben. Gelesene Texte oder URLs nie ungeprüft per innerHTML einfügen oder automatisch aufrufen, sonst drohen XSS oder Phishing. makeReadOnly() macht ein Tag dauerhaft schreibgeschützt, und das lässt sich nicht rückgängig machen.
  • Den reading-Listener am besten vor oder direkt nach await scan() registrieren, damit keine Ereignisse verloren gehen.