Signatur
Beschreibung
Die schreibgeschützte Eigenschaft ServiceWorkerContainer.controller gibt das ServiceWorker-Objekt zurück, das die aktuelle Seite gerade kontrolliert. Nur dieser Worker fängt die Netzwerkanfragen der Seite im fetch-Ereignis ab. Wird die Seite nicht kontrolliert, ist der Wert null.
Gebraucht wird die Eigenschaft vor allem, um Nachrichten an den Service Worker zu senden (controller.postMessage()) und um zu prüfen, ob die Seite schon offline-fähig ist. Außerdem lässt sich damit feststellen, ob ein neu installierter Worker die Kontrolle übernommen hat. Das passiert in Kombination mit dem Ereignis controllerchange.
Wichtig: Bei der ersten Registrierung ist controller in der Regel null, obwohl der Worker schon installiert und aktiv ist. Die Seite wird erst beim nächsten Laden kontrolliert, außer der Worker ruft in seinem activate-Handler clients.claim() auf. Nach einem erzwungenen Neuladen (Shift+Reload) ist controller ebenfalls absichtlich null.
Rückgabewert
ServiceWorker im Zustand activating oder activated, sonst null.Beispiele
Prüfen, ob die Seite kontrolliert wird
if ('serviceWorker' in navigator) {
const { controller } = navigator.serviceWorker;
if (controller) {
console.log('Kontrolliert von:', controller.scriptURL);
} else {
console.log('Seite wird (noch) nicht von einem Service Worker kontrolliert.');
}
}
Nachricht an den kontrollierenden Worker senden
// Seite: Cache gezielt leeren lassen
const clearCache = () => {
const sw = navigator.serviceWorker.controller;
if (!sw) {
console.warn('Kein aktiver Controller – Nachricht nicht gesendet.');
return;
}
sw.postMessage({ type: 'CLEAR_CACHE', cacheName: 'api-v1' });
};
// sw.js
// self.addEventListener('message', (event) => {
// if (event.data?.type === 'CLEAR_CACHE') {
// event.waitUntil(caches.delete(event.data.cacheName));
// }
// });
clearCache();
Auf den Wechsel des Controllers reagieren
const init = async () => {
await navigator.serviceWorker.register('/sw.js');
// Wartet, bis die Seite tatsächlich kontrolliert wird
const controller = navigator.serviceWorker.controller ??
await new Promise((resolve) => {
navigator.serviceWorker.addEventListener(
'controllerchange',
() => resolve(navigator.serviceWorker.controller),
{ once: true }
);
});
console.log('Jetzt kontrolliert, Zustand:', controller.state);
};
init();
// Wichtig · Fallstricke
- Erstbesuch: Direkt nach
register()istcontrollermeistnull. Soll die Seite sofort kontrolliert werden, muss der Workerself.clients.claim()imactivate-Ereignis aufrufen. Das Beispiel mitcontrollerchangewartet sonst bis zum nächsten Laden. - Hard-Reload: Nach Shift+Reload bzw. „Cache leeren und neu laden“ umgeht der Browser den Service Worker, und
controlleristnull. - Nicht mit
registration.activeverwechseln: Ein Worker kann aktiv sein, ohne die aktuelle Seite zu kontrollieren, etwa wenn die Seite außerhalb seinesscopeliegt. - Update-Wechsel: Nach
skipWaiting()eines neuen Workers ändert sichcontroller, undcontrollerchangewird ausgelöst. Referenzen auf den alten Controller also nicht dauerhaft zwischenspeichern. - Sicherer Kontext:
navigator.serviceWorkergibt es nur über HTTPS (oderlocalhost). In privaten Fenstern einiger Browser (z. B. Firefox) ist die Eigenschaft nicht verfügbar. Deshalb vorher mit'serviceWorker' in navigatorprüfen. - Sicherheit: Daten, die über
postMessagehin- und hergeschickt werden, im Worker immer prüfen. Nur strukturiert klonbare Werte sind erlaubt.