Signatur
Beschreibung
Die Eigenschaft ports des ExtendableMessageEvent enthält alle MessagePort-Objekte, die der Absender beim Aufruf von postMessage() im Transfer-Array mitgeschickt hat. Meist ist das der Port port2 eines MessageChannel, den die Seite erzeugt hat, damit der Service Worker direkt und gezielt antworten kann.
Das ist das übliche Muster für eine Anfrage-Antwort-Kommunikation zwischen Seite und Service Worker: Die Seite behält port1 und wartet dort auf die Antwort, der Service Worker schreibt über event.ports[0].postMessage() zurück. So muss man Antworten nicht über alle Clients verteilen und keine eigenen Kennungen verwalten, um sie zuzuordnen.
Wurden keine Ports übertragen, ist ports ein leeres Array. Das Array ist eingefroren (frozen) und lässt sich nicht verändern. Die Ports selbst können Sie aber ganz normal verwenden, also Nachrichten senden, auf Nachrichten hören und sie schließen.
Rückgabewert
MessagePort-Objekten. Wurden keine Ports mitgeschickt, ist es leer.Beispiele
Seite: MessageChannel an den Service Worker schicken
// main.js
const askServiceWorker = async (payload) => {
const registration = await navigator.serviceWorker.ready;
return new Promise((resolve, reject) => {
const channel = new MessageChannel();
channel.port1.onmessage = (event) => {
channel.port1.close();
event.data.error ? reject(event.data.error) : resolve(event.data);
};
// port2 wird übertragen und landet in event.ports im Service Worker
registration.active.postMessage(payload, [channel.port2]);
});
};
const result = await askServiceWorker({ type: 'CACHE_SIZE' });
console.log(result);
Service Worker: über event.ports[0] antworten
// sw.js
self.addEventListener('message', (event) => {
const [replyPort] = event.ports;
if (!replyPort) return; // kein Antwortkanal mitgeschickt
if (event.data?.type === 'CACHE_SIZE') {
// waitUntil hält den Service Worker aktiv, bis die Antwort raus ist
event.waitUntil((async () => {
const cache = await caches.open('v1');
const keys = await cache.keys();
replyPort.postMessage({ entries: keys.length });
})());
} else {
replyPort.postMessage({ error: 'Unbekannter Typ' });
}
});
Prüfen, wie viele Ports angekommen sind
// sw.js
self.addEventListener('message', (event) => {
console.log('Anzahl Ports:', event.ports.length);
console.log('Eingefroren:', Object.isFrozen(event.ports));
});
// Wichtig · Fallstricke
- Ports kommen nur an, wenn sie im Transfer-Array (zweites Argument von
postMessage()) stehen. Stecken sie nur im Nachrichtenobjekt, wirft der Aufruf einenDataCloneError. - Ein übertragener Port ist beim Absender danach unbrauchbar (neutered). Die Seite muss
port1behalten undport2übertragen. - Asynchrone Arbeit vor der Antwort gehört in
event.waitUntil(). Sonst kann der Browser den Service Worker beenden, bevor die Antwort gesendet ist. - Das Array ist eingefroren:
push()oder Zuweisungen werfen im Strict Mode einenTypeError. - Wenn Sie
onmessagesetzen, wird der Port automatisch gestartet. MitaddEventListener('message', …)müssen Sie dagegenport.start()selbst aufrufen. - Schließen Sie nicht mehr benötigte Ports mit
close(), damit keine Speicherlecks entstehen. - Nur im Service-Worker-Kontext verfügbar, der einen sicheren Ursprung (HTTPS oder localhost) voraussetzt.