Signatur
Beschreibung
Der Konstruktor BroadcastChannel() erstellt eine Verbindung zu einem benannten Nachrichtenkanal. Alle Kontexte mit demselben Ursprung (Schema, Host, Port), die einen Kanal mit identischem Namen öffnen, sind miteinander verbunden. Das gilt für Tabs, Fenster, iframes, Web Worker und Service Worker. Eine Nachricht, die per postMessage() gesendet wird, erhalten alle anderen Instanzen dieses Kanals, der Sender selbst jedoch nicht.
Typische Einsatzfälle sind das gleichzeitige Abmelden in allen Tabs, das Abgleichen von Warenkorb- oder Theme-Einstellungen, das Invalidieren von Caches und die Koordination zwischen Service Worker und Seiten. Im Gegensatz zu window.postMessage() braucht man keine Referenz auf das Zielfenster, und anders als beim storage-Event lassen sich beliebige strukturiert klonbare Daten übertragen, z. B. Objekte, Map, Blob oder ArrayBuffer.
Einen Kanal muss man nicht vorher anlegen: Er entsteht, sobald die erste Instanz mit diesem Namen erzeugt wird. Wird eine Instanz nicht mehr gebraucht, sollte man sie mit close() schließen. Dann kann der Garbage Collector sie freigeben, und sie empfängt keine Nachrichten mehr.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $channelName Pflicht | string | Name des Kanals, mit dem sich die Instanz verbindet. Andere Werte als Strings werden in einen String umgewandelt (z. B. wird undefined zu "undefined"). Der Name gilt nur innerhalb des jeweiligen Ursprungs. |
Rückgabewert
BroadcastChannel-Instanz, die mit dem benannten Kanal verbunden ist. Sie bietet name, postMessage(), close() sowie die Events message und messageerror.Beispiele
Kanal erzeugen, senden und empfangen
// In Tab A und Tab B mit demselben Ursprung ausführen
const channel = new BroadcastChannel('app-sync');
channel.addEventListener('message', (event) => {
console.log('Empfangen:', event.data);
});
// Nur die ANDEREN Tabs erhalten die Nachricht
channel.postMessage({ type: 'greeting', text: 'Hallo aus einem anderen Tab!' });
Logout in allen Tabs gleichzeitig
const authChannel = new BroadcastChannel('auth');
const logout = async () => {
await fetch('/api/logout', { method: 'POST' });
authChannel.postMessage({ type: 'logout' });
window.location.href = '/login';
};
authChannel.onmessage = ({ data }) => {
if (data.type === 'logout') {
window.location.href = '/login';
}
};
document.querySelector('#logout-btn')?.addEventListener('click', logout);
Kommunikation mit einem Web Worker und sauberes Schließen
// worker.js
const bc = new BroadcastChannel('jobs');
bc.onmessage = ({ data }) => {
const result = data.numbers.reduce((a, b) => a + b, 0);
bc.postMessage({ id: data.id, result });
};
// main.js
const worker = new Worker('worker.js');
const jobs = new BroadcastChannel('jobs');
jobs.onmessage = ({ data }) => {
console.log(`Job ${data.id}: ${data.result}`);
jobs.close(); // Instanz freigeben
};
jobs.postMessage({ id: 1, numbers: [1, 2, 3, 4] });
Fehler beim Deserialisieren abfangen
const channel = new BroadcastChannel('data');
console.log(channel.name);
channel.addEventListener('messageerror', (event) => {
console.error('Nachricht konnte nicht deserialisiert werden', event);
});
try {
// Funktionen sind nicht strukturiert klonbar
channel.postMessage({ callback: () => {} });
} catch (err) {
console.error(err.name);
}
// Wichtig · Fallstricke
- Nur gleicher Ursprung: Andere Ursprünge können nicht mitlesen. Für ursprungsübergreifende Kommunikation braucht man
window.postMessage()und muss dortevent.originprüfen. - Speicher-Partitionierung: Moderne Browser (Firefox, Safari, Chrome) trennen Kanäle zusätzlich nach der Top-Level-Site. Ein eingebettetes iframe von
a.cominb.comteilt seinen Kanal daher nicht mit einem direkt geöffneten Tab vona.com. - Sender empfängt nichts: Die sendende Instanz bekommt ihre eigene Nachricht nicht. Andere Instanzen mit demselben Namen im selben Kontext erhalten sie jedoch.
- Strukturiertes Klonen: Funktionen, DOM-Knoten und manche Objekte lassen sich nicht übertragen. Dann wirft
postMessage()einenDataCloneError. Kann der Empfänger eine Nachricht nicht deserialisieren, löst dasmessageerroraus. - Keine Zustellgarantie für spätere Instanzen: Nachrichten werden nicht gepuffert. Wer den Kanal erst später öffnet, erhält frühere Nachrichten nicht.
- Nach
close()wirftpostMessage()einenInvalidStateError. - Sicherheit: Eingehende Daten stammen zwar vom selben Ursprung, sollten aber trotzdem geprüft werden. Nutzt man sie z. B. per
innerHTML, droht XSS, wenn ein anderes Skript auf dem Ursprung kompromittiert ist. - Kompatibilität: Unterstützt von Chrome 54+, Firefox 38+, Edge 79+ und Safari 15.4+. In Node.js ist der Konstruktor ab Version 18 global verfügbar, zuvor über
worker_threads.