Signatur
Beschreibung
Das Ereignis messageerror ist das Gegenstück zum Ereignis message. Es wird am Window-Objekt ausgelöst, wenn eine Nachricht aus einem anderen Fenster, einem iframe oder einem Opener zwar ankommt, der Browser sie aber nicht deserialisieren kann (Structured-Clone-Algorithmus). Statt eines message-Ereignisses bekommst du dann ein messageerror-Ereignis vom Typ MessageEvent, dessen Eigenschaft data auf null gesetzt ist.
Wichtig: Objekte, die gar nicht klonbar sind (z. B. Funktionen oder DOM-Knoten), führen schon beim Senden zu einer DataCloneError-Ausnahme in postMessage() und lösen kein messageerror aus. Das Ereignis tritt erst auf, wenn die Serialisierung beim Sender geklappt hat, die Deserialisierung beim Empfänger aber scheitert. Typische Fälle sind ein SharedArrayBuffer, das an ein Fenster ohne Cross-Origin-Isolation (fehlende COOP/COEP-Header) oder über Agent-Cluster-Grenzen hinweg geschickt wird, oder Objekte wie WebAssembly.Module, die sich zwischen verschiedenen Agent-Clustern nicht übertragen lassen.
Du registrierst den Handler mit window.addEventListener("messageerror", handler) oder über die Eigenschaft window.onmessageerror. Im Handler solltest du den Fehler protokollieren und, falls nötig, beim Absender über event.source eine Ersatzform der Daten anfordern, zum Beispiel einen normalen ArrayBuffer anstelle eines SharedArrayBuffer.
Das Ereignis ist nicht abbrechbar und steigt nicht auf (bubbles). Dasselbe Ereignis gibt es auch bei Worker, MessagePort, BroadcastChannel und DedicatedWorkerGlobalScope.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $type Pflicht | string | Der Ereignistyp, hier immer "messageerror". |
|
| $handler Pflicht | (event: MessageEvent) => void | Callback, der ein MessageEvent bekommt. Relevante Eigenschaften: origin, source, lastEventId, ports. data ist null. |
|
| $options | boolean | AddEventListenerOptions | false | Optionen wie once, signal oder capture, wie bei jedem addEventListener-Aufruf. |
Rückgabewert
addEventListener gibt nichts zurück. Der Handler bekommt ein MessageEvent.Beispiele
messageerror mit addEventListener überwachen
// Empfängerseite, z. B. in einem iframe
const ERLAUBTE_ORIGIN = "https://app.example.com";
window.addEventListener("message", (event) => {
if (event.origin !== ERLAUBTE_ORIGIN) return;
console.log("Nachricht erhalten:", event.data);
});
window.addEventListener("messageerror", (event) => {
if (event.origin !== ERLAUBTE_ORIGIN) return;
console.warn("Nachricht konnte nicht deserialisiert werden von:", event.origin);
console.log("data:", event.data);
});
Über die onmessageerror-Eigenschaft und Ersatzdaten anfordern
window.onmessageerror = (event) => {
console.error("Deserialisierung fehlgeschlagen");
// Absender bitten, die Daten in einer übertragbaren Form erneut zu schicken
event.source?.postMessage(
{ typ: "resend", format: "arraybuffer" },
event.origin
);
};
// Handler später wieder entfernen
// window.onmessageerror = null;
Listener mit AbortController sauber entfernen
const controller = new AbortController();
const beiFehler = (event) => {
console.warn(`messageerror von ${event.origin || "unbekannt"}`);
};
window.addEventListener("messageerror", beiFehler, { signal: controller.signal });
// Später, z. B. beim Abbauen einer Komponente:
controller.abort();
// Gleichwertig: window.removeEventListener("messageerror", beiFehler);
Unterschied zu DataCloneError beim Senden
const iframe = document.querySelector("iframe");
try {
// Funktionen sind nicht klonbar: Fehler tritt schon beim Sender auf
iframe.contentWindow.postMessage({ fn: () => 1 }, "*");
} catch (err) {
console.log(err.name); // kein messageerror beim Empfänger!
}
// Wichtig · Fallstricke
- Selten, aber wichtig:
messageerrortritt nur auf, wenn das Deserialisieren beim Empfänger scheitert. Ist das Objekt gar nicht klonbar, wirft schonpostMessage()beim Sender einenDataCloneError. - SharedArrayBuffer: Das ist der häufigste Auslöser. Das empfangende Dokument muss cross-origin-isoliert sein (
Cross-Origin-Opener-Policy: same-originundCross-Origin-Embedder-Policy: require-corp). Ob das der Fall ist, liest du anself.crossOriginIsolatedab. - Sicherheit: Prüfe auch hier immer
event.origin, bevor du überevent.sourceantwortest. Gib als Ziel-Origin nie pauschal\"*\"an, wenn du sensible Daten schickst. event.dataist immernull. Welcher Fehler genau aufgetreten ist, erfährst du nicht.- Kompatibilität: Wird in allen aktuellen Browsern unterstützt (Chrome 60+, Firefox 57+, Safari 16.4+). Ältere Browser lösen das Ereignis nicht aus. Deine Logik sollte deshalb nicht allein davon abhängen, zusätzlich helfen Zeitlimits oder Bestätigungsnachrichten.