Start · Sprachen · JavaScript · Referenz · Window: messageerror

Window: messageerror

Ereignis

Wird am <code>Window</code> ausgelöst, wenn eine per <code>postMessage()</code> empfangene Nachricht nicht deserialisiert werden kann.

seit JavaScript Baseline: alle modernen Browser (seit ca. 2017/201 Kategorie: webapi

Signatur

window.addEventListener("messageerror", handler)

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

Typ
void
Beschreibung
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);
});
Nachricht konnte nicht deserialisiert werden von: https://app.example.com data: null

Ü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;
Deserialisierung fehlgeschlagen

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!
}
DataCloneError

// Wichtig · Fallstricke

  • Selten, aber wichtig: messageerror tritt nur auf, wenn das Deserialisieren beim Empfänger scheitert. Ist das Objekt gar nicht klonbar, wirft schon postMessage() beim Sender einen DataCloneError.
  • SharedArrayBuffer: Das ist der häufigste Auslöser. Das empfangende Dokument muss cross-origin-isoliert sein (Cross-Origin-Opener-Policy: same-origin und Cross-Origin-Embedder-Policy: require-corp). Ob das der Fall ist, liest du an self.crossOriginIsolated ab.
  • Sicherheit: Prüfe auch hier immer event.origin, bevor du über event.source antwortest. Gib als Ziel-Origin nie pauschal \"*\" an, wenn du sensible Daten schickst.
  • event.data ist immer null. 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.