Start · Sprachen · JavaScript · Referenz · BroadcastChannel: message

BroadcastChannel: message

Ereignis

Wird auf einem <code>BroadcastChannel</code> ausgelöst, wenn ein anderer Kontext gleichen Ursprungs per <code>postMessage()</code> eine Nachricht auf diesem Kanal sendet.

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

Signatur

broadcastChannel.addEventListener("message", handler)

Beschreibung

Das message-Ereignis tritt auf, wenn auf einem BroadcastChannel mit demselben Kanalnamen eine Nachricht eintrifft. Der Sender kann ein anderes Tab, ein anderes Fenster, ein iframe oder ein Worker (Dedicated, Shared, Service Worker) sein, sofern er zum gleichen Ursprung (Origin) gehört. Der sendende Kanal selbst bekommt seine eigene Nachricht nicht.

Den Handler registriert man entweder mit channel.addEventListener("message", handler) oder über die Eigenschaft channel.onmessage = handler. Der Handler erhält ein MessageEvent. Die gesendeten Daten stehen in event.data. Sie wurden mit dem Structured-Clone-Algorithmus kopiert, deshalb sind auch Objekte, Arrays, Map, Set, Date oder Blob möglich.

Typische Einsätze sind das Abgleichen des Zustands zwischen Tabs (Abmelden in allen Tabs, Warenkorb-Aktualisierung, Theme-Wechsel), das Invalidieren von Caches oder Nachrichten vom Service Worker an alle offenen Seiten. Im Gegensatz zu window.postMessage() braucht man keine Referenz auf das Zielfenster, denn jeder Teilnehmer abonniert einfach den Kanalnamen.

Parameter

Name Typ Default Beschreibung
$type Pflicht string Der Ereignistyp, hier "message".
$handler Pflicht (event: MessageEvent) => void Callback, der ein MessageEvent bekommt. Wichtige Eigenschaften: data (die geklonte Nachricht) und origin. source und ports sind bei BroadcastChannel immer null bzw. leer.
$options boolean|AddEventListenerOptions false Optionale Listener-Optionen wie once oder signal (AbortSignal zum Entfernen).

Rückgabewert

Typ
void
Beschreibung
addEventListener() gibt nichts zurück. Der Handler erhält ein MessageEvent.

Beispiele

Abmelden in allen Tabs synchronisieren

// In jedem Tab ausführen
const authChannel = new BroadcastChannel("auth");

authChannel.addEventListener("message", (event) => {
  if (event.data?.type === "logout") {
    console.log("Abgemeldet in anderem Tab – leite um…");
    window.location.href = "/login";
  }
});

// Beim Klick auf „Abmelden“ im aktuellen Tab
document.querySelector("#logout")?.addEventListener("click", () => {
  authChannel.postMessage({ type: "logout", at: Date.now() });
  window.location.href = "/login";
});
Abgemeldet in anderem Tab – leite um… (nur in den ANDEREN Tabs)

onmessage-Eigenschaft und Aufräumen mit close()

const themeChannel = new BroadcastChannel("theme");

themeChannel.onmessage = ({ data }) => {
  document.documentElement.dataset.theme = data.theme;
  console.log(`Theme gewechselt auf: ${data.theme}`);
};

// Andere Tabs informieren
themeChannel.postMessage({ theme: "dark" });

// Listener entfernen und Kanal schließen, z. B. beim Verlassen der Seite
window.addEventListener("pagehide", () => {
  themeChannel.onmessage = null;
  themeChannel.close();
});
Theme gewechselt auf: dark (in den anderen Tabs)

Listener per AbortSignal entfernen

const cartChannel = new BroadcastChannel("cart");
const controller = new AbortController();

cartChannel.addEventListener(
  "message",
  (event) => {
    const { items } = event.data;
    console.log(`Warenkorb aktualisiert: ${items.length} Artikel`);
  },
  { signal: controller.signal }
);

// Später: Listener abmelden, ohne die Handler-Referenz zu brauchen
controller.abort();
Warenkorb aktualisiert: 3 Artikel (solange der Listener aktiv ist)

Service Worker benachrichtigt alle Seiten

// sw.js
const swChannel = new BroadcastChannel("sw-updates");
self.addEventListener("activate", () => {
  swChannel.postMessage({ type: "new-version", version: "2.1.0" });
});

// main.js (Seite)
const updates = new BroadcastChannel("sw-updates");
updates.addEventListener("message", ({ data }) => {
  if (data.type === "new-version") {
    console.log(`Neue Version ${data.version} verfügbar – bitte neu laden.`);
  }
});
Neue Version 2.1.0 verfügbar – bitte neu laden.

// Wichtig · Fallstricke

  • Kein Echo: Die sendende BroadcastChannel-Instanz bekommt ihre eigene Nachricht nicht. Eine zweite Instanz mit gleichem Namen im selben Kontext bekommt sie aber schon.
  • Nur gleicher Ursprung: Die Kommunikation funktioniert nur zwischen Kontexten mit identischem Origin (Schema, Host, Port). Außerdem trennen Browser mit Storage-Partitionierung die Kanäle nach Top-Level-Site, sodass ein eingebettetes Drittanbieter-iframe andere Kanäle sieht als dieselbe Seite als Top-Level-Dokument.
  • Nicht klonbare Daten: Funktionen, DOM-Knoten und Klasseninstanzen samt Prototyp lassen sich nicht übertragen. Ist die Deserialisierung beim Empfänger nicht möglich, wird statt message das Ereignis messageerror ausgelöst. postMessage() selbst wirft bei nicht klonbaren Werten eine DataCloneError-Ausnahme.
  • Sicherheit: Jedes Skript desselben Ursprungs kann auf dem Kanal senden. Behandle event.data deshalb als nicht vertrauenswürdig: Struktur prüfen und niemals ungeprüft in innerHTML oder eval übernehmen.
  • Keine Zustellgarantie und keine Pufferung: Nachrichten erreichen nur Kontexte, die in diesem Moment einen offenen Kanal haben. Für dauerhaften Zustand zusätzlich localStorage oder IndexedDB verwenden.
  • Aufräumen: Mit close() den Kanal schließen, wenn er nicht mehr gebraucht wird. Ein offener Kanal kann den Back/Forward-Cache verhindern und hält Ressourcen fest.
  • Kompatibilität: Wird von Chrome 54+, Firefox 38+, Edge 79+ und Safari 15.4+ unterstützt, in Workern ebenso. Ältere Safari-Versionen brauchen einen Ausweichweg, etwa über das storage-Ereignis.