Start · Sprachen · JavaScript · Referenz · BroadcastChannel.postMessage()

BroadcastChannel.postMessage()

Methode

Sendet eine per Structured Clone kopierte Nachricht an alle anderen <code>BroadcastChannel</code>-Instanzen mit gleichem Namen und gleichem Ursprung.

seit JavaScript Baseline: alle modernen Browser (Safari ab 15.4), Kategorie: webapi

Signatur

BroadcastChannel.prototype.postMessage(message)

Beschreibung

postMessage() verschickt eine Nachricht über einen BroadcastChannel. Empfänger sind alle anderen Instanzen mit demselben Kanalnamen im selben Ursprung (Origin). Das können andere Tabs, Fenster, iframes, Web Worker oder Service Worker sein. Die sendende Instanz bekommt ihre eigene Nachricht nicht. Eine zweite Instanz mit demselben Namen im selben Kontext empfängt sie dagegen schon.

Die Nachricht wird mit dem Structured-Clone-Algorithmus kopiert. Damit lassen sich neben einfachen Werten auch Objekte, Arrays, Map, Set, Date, Blob, ArrayBuffer und ähnliche Typen senden. Funktionen, DOM-Knoten und Objekte mit Symbol-Schlüsseln lassen sich nicht kopieren. Anders als bei Window.postMessage() gibt es keine Übertragung (Transfer-Liste). Die Daten werden also immer kopiert.

Typische Einsatzfälle sind die Synchronisierung zwischen Tabs: Logout in allen Fenstern, Aktualisieren eines Warenkorbs, Verteilen von Theme-Änderungen oder das Signal, dass ein Service Worker neue Inhalte zwischengespeichert hat. Die Zustellung ist asynchron. Empfänger reagieren über das Ereignis message und lesen die Daten aus event.data.

Parameter

Name Typ Default Beschreibung
$message Pflicht any (structured-cloneable) Die zu sendenden Daten. Erlaubt ist jeder Wert, den der Structured-Clone-Algorithmus kopieren kann, z. B. Objekte, Arrays, Date, Map, Blob oder ArrayBuffer.

Rückgabewert

Typ
void
Beschreibung
Kein Rückgabewert (undefined). Ob und wann die Nachricht ankommt, wird nicht bestätigt.

Beispiele

Einfache Nachricht zwischen Tabs senden

// In beiden Tabs ausführen
const channel = new BroadcastChannel('app-events');

channel.addEventListener('message', (event) => {
  console.log('Empfangen:', event.data);
});

// In einem Tab:
channel.postMessage({ type: 'greeting', text: 'Hallo aus Tab A' });
// Im anderen Tab: Empfangen: { type: 'greeting', text: 'Hallo aus Tab A' }

Logout in allen Tabs synchronisieren

const authChannel = new BroadcastChannel('auth');

const logout = async () => {
  await fetch('/api/logout', { method: 'POST' });
  authChannel.postMessage({ type: 'logout', at: Date.now() });
  location.href = '/login';
};

authChannel.onmessage = ({ data }) => {
  if (data.type === 'logout') {
    console.log('Abgemeldet in anderem Tab um', new Date(data.at).toLocaleTimeString());
    location.href = '/login';
  }
};

document.querySelector('#logout-btn')?.addEventListener('click', logout);
Abgemeldet in anderem Tab um 14:32:05

Service Worker meldet Cache-Update an alle Seiten

// sw.js
const updates = new BroadcastChannel('sw-updates');

self.addEventListener('activate', (event) => {
  event.waitUntil((async () => {
    await caches.open('v2');
    updates.postMessage({ type: 'cache-updated', version: 'v2' });
  })());
});

// main.js
const updatesClient = new BroadcastChannel('sw-updates');
updatesClient.onmessage = ({ data }) => {
  if (data.type === 'cache-updated') {
    console.log(`Neue Version ${data.version} verfügbar – bitte neu laden.`);
  }
};
Neue Version v2 verfügbar – bitte neu laden.

Fehler bei nicht klonbaren Daten abfangen

const channel = new BroadcastChannel('demo');

try {
  channel.postMessage({ callback: () => {} });
} catch (err) {
  console.log(err.name);
}

channel.close();
try {
  channel.postMessage('nach close');
} catch (err) {
  console.log(err.name);
}
DataCloneError InvalidStateError

// Wichtig · Fallstricke

  • Kein Echo: Die sendende Instanz empfängt ihre eigene Nachricht nicht. Andere Instanzen mit demselben Namen im selben Kontext empfangen sie aber.
  • Ausnahmen: Nicht klonbare Daten wie Funktionen oder DOM-Knoten lösen DataCloneError aus. Ein Aufruf nach close() löst InvalidStateError aus.
  • Deserialisierungsfehler: Kann ein Empfänger die Daten nicht rekonstruieren, wird dort messageerror statt message ausgelöst.
  • Nur gleicher Ursprung: Für Kommunikation über Ursprünge hinweg ist Window.postMessage() nötig. Dort sollte man immer targetOrigin und event.origin prüfen. Browser mit Storage-Partitionierung (z. B. Safari, Firefox, Chrome) trennen Kanäle zusätzlich nach Top-Level-Site. Ein eingebettetes iframe erreicht dann nicht unbedingt denselben Ursprung als eigenständigen Tab.
  • Sicherheit: Jeder Code im selben Ursprung kann mitlesen und Nachrichten einschleusen. Übertragen Sie daher keine Geheimnisse wie Tokens ungeschützt und prüfen Sie eingehende Daten, bevor Sie sie z. B. per innerHTML ins DOM schreiben (XSS).
  • Keine Transfer-Liste: Große ArrayBuffer werden immer kopiert. Das kann Speicher und Zeit kosten.
  • Keine Zustellgarantie: Nachrichten werden nicht gepuffert. Tabs, die später geöffnet werden, erhalten frühere Nachrichten nicht. Dauerhafter Zustand gehört zusätzlich in localStorage oder IndexedDB.
  • Kanäle, die nicht mehr gebraucht werden, mit close() schließen, damit sie vom Garbage Collector freigegeben werden können.