Start · Sprachen · JavaScript · Referenz · ExtendableMessageEvent.source

ExtendableMessageEvent.source

Eigenschaft

Schreibgeschützte Eigenschaft, die das Absender-Objekt einer Nachricht an den Service Worker liefert: <code>Client</code>, <code>ServiceWorker</code> oder <code>MessagePort</code>.

seit JavaScript Baseline: alle modernen Browser (Service Worker) Kategorie: webapi

Signatur

ExtendableMessageEvent.source

Beschreibung

Die schreibgeschützte Eigenschaft source der Schnittstelle ExtendableMessageEvent verweist auf das Objekt, das die Nachricht an den Service Worker geschickt hat. Meist ist das ein Client bzw. WindowClient, also ein Tab, ein Fenster oder ein Worker, der navigator.serviceWorker.controller.postMessage() oder registration.active.postMessage() aufgerufen hat.

Wofür braucht man das? Mit source kann der Service Worker gezielt dem Absender antworten, ohne alle Clients über clients.matchAll() durchsuchen zu müssen. Außerdem lassen sich über source.id, source.url und source.type Absender unterscheiden, etwa um Nachrichten aus fremden Pfaden abzulehnen.

Der Typ ist laut Spezifikation Client | ServiceWorker | MessagePort | null. Kommt die Nachricht von einem anderen Service Worker, ist source ein ServiceWorker-Objekt. Wurde das Ereignis synthetisch mit new ExtendableMessageEvent() erzeugt und dabei keine Quelle angegeben, ist der Wert null.

Rückgabewert

Typ
Client | ServiceWorker | MessagePort | null
Beschreibung
Das Absender-Objekt der Nachricht. Bei Seiten ist es meist ein WindowClient mit id, url, type und postMessage(). Gibt es keine Quelle, ist der Wert null.

Beispiele

Dem Absender direkt antworten (Service Worker)

// sw.js
self.addEventListener('message', (event) => {
  const client = event.source;
  if (!client) return;

  if (event.data?.type === 'PING') {
    client.postMessage({ type: 'PONG', clientId: client.id });
  }
});

// main.js (Seite)
navigator.serviceWorker.addEventListener('message', (e) => {
  console.log('Antwort vom SW:', e.data.type);
});
const reg = await navigator.serviceWorker.ready;
reg.active.postMessage({ type: 'PING' });
Antwort vom SW: PONG

Absender prüfen und asynchrone Arbeit mit waitUntil absichern

// sw.js
self.addEventListener('message', (event) => {
  const src = event.source;

  // Nur Fenster-Clients aus dem eigenen Ursprung akzeptieren
  if (!(src instanceof WindowClient)) return;
  const url = new URL(src.url);
  if (url.origin !== self.location.origin) return;

  if (event.data?.type === 'CACHE_URLS') {
    event.waitUntil((async () => {
      const cache = await caches.open('v1');
      await cache.addAll(event.data.urls);
      src.postMessage({ type: 'CACHED', count: event.data.urls.length });
    })());
  }
});

Absender-Typ unterscheiden

// sw.js
self.addEventListener('message', (event) => {
  const { source } = event;
  if (source === null) {
    console.log('Keine Quelle (synthetisches Event)');
  } else if (source instanceof Client) {
    console.log(`Client (${source.type}):`, source.url);
  } else if (source instanceof ServiceWorker) {
    console.log('Anderer Service Worker:', source.scriptURL);
  } else if (source instanceof MessagePort) {
    console.log('Nachricht über MessagePort');
  }
});
Client (window): https://example.com/app/

// Wichtig · Fallstricke

  • Nur im Service-Worker-Kontext: ExtendableMessageEvent kommt ausschließlich beim message-Ereignis im ServiceWorkerGlobalScope vor. Auf der Seite selbst empfängt man ein normales MessageEvent, dessen source dort ein ServiceWorker ist.
  • Auf null prüfen: Vor dem Aufruf von source.postMessage() sollte man prüfen, ob source gesetzt ist, sonst gibt es einen TypeError.
  • Lebensdauer: Der Service Worker kann nach dem Ereignis beendet werden. Asynchrone Antworten (Cache, fetch) gehören deshalb in event.waitUntil().
  • Sicherheit: Nachrichten kommen zwar nur von Clients desselben Ursprungs, trotzdem sollte man event.data validieren und bei Bedarf source.url prüfen. Ungeprüfte Daten gehören nicht in Cache-Schlüssel oder URLs.
  • Kompatibilität: Wird in Chrome, Edge, Firefox und Safari (ab 11.1) unterstützt. Service Worker brauchen HTTPS oder localhost. Firefox stellt Service Worker in privaten Fenstern teilweise nicht bereit.