Signatur
Beschreibung
Die Schnittstelle ServiceWorkerContainer ist der Einstiegspunkt der Service Worker API auf Seiten des Dokuments (oder eines Workers). Man erzeugt sie nicht selbst, sondern erreicht sie über navigator.serviceWorker. Über sie registriert man Service Worker, fragt bestehende Registrierungen ab und reagiert auf Wechsel des steuernden Workers.
Die wichtigsten Mitglieder:
register(scriptURL, options)– registriert einen Service Worker und liefert einPromise<ServiceWorkerRegistration>.getRegistration(clientURL)/getRegistrations()– liefern eine bzw. alle Registrierungen für den aktuellen Origin.ready– ein Promise, das erfüllt wird, sobald eine Registrierung für die Seite einen aktiven Worker hat. Es wird nie abgelehnt.controller– derServiceWorker, der die Seite aktuell steuert, odernull(z. B. nach einem harten Neuladen mit Umschalt-Taste oder beim allerersten Besuch).startMessages()– gibt Nachrichten frühzeitig frei, die perpostMessage()vom Service Worker kommen.- Events:
controllerchange(neuer steuernder Worker),message(Nachricht vom Worker),messageerror(Nachricht nicht deserialisierbar).
Typische Anwendungen sind Progressive Web Apps mit Offline-Fähigkeit, Push-Benachrichtigungen, Hintergrund-Synchronisation und Caching-Strategien. Die Registrierung erfolgt meist nach dem load-Event, damit das Laden der Seite selbst nicht ausgebremst wird.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $scriptURL Pflicht | string | URL | TrustedScriptURL | Parameter von register(): URL des Service-Worker-Skripts. Muss aus demselben Origin stammen. |
|
| $options.scope | string | Verzeichnis des Skripts | Pfad, den der Worker steuern soll. Darf ohne Service-Worker-Allowed-Header nicht oberhalb des Skript-Verzeichnisses liegen. |
| $options.type | "classic" | "module" | "classic" | Bei "module" wird das Skript als ES-Modul geladen (mit import). |
| $options.updateViaCache | "imports" | "all" | "none" | "imports" | Legt fest, ob beim Update-Check der HTTP-Cache für das Skript und importierte Skripte verwendet wird. |
| $clientURL | string | URL | URL des aktuellen Dokuments | Parameter von getRegistration(): URL, für die die passende Registrierung gesucht wird. |
Rückgabewert
navigator.serviceWorker liefert die ServiceWorkerContainer-Instanz des aktuellen Kontexts. In unsicheren Kontexten (kein HTTPS) ist die Eigenschaft undefined.Beispiele
Service Worker mit Feature-Erkennung registrieren
if ('serviceWorker' in navigator) {
window.addEventListener('load', async () => {
try {
const registration = await navigator.serviceWorker.register('/sw.js', {
scope: '/',
type: 'module'
});
console.log('Registriert für Scope:', registration.scope);
} catch (err) {
console.error('Registrierung fehlgeschlagen:', err);
}
});
}
Auf aktiven Worker warten und Nachricht senden
const registration = await navigator.serviceWorker.ready;
registration.active.postMessage({ type: 'CACHE_URLS', urls: ['/offline.html'] });
// Antworten des Service Workers empfangen
navigator.serviceWorker.addEventListener('message', (event) => {
console.log('Vom Service Worker:', event.data);
});
Seite nach Update des Workers neu laden
let refreshing = false;
navigator.serviceWorker.addEventListener('controllerchange', () => {
if (refreshing) return; // Endlosschleife vermeiden
refreshing = true;
window.location.reload();
});
console.log('Aktueller Controller:', navigator.serviceWorker.controller?.scriptURL ?? 'keiner');
Alle Registrierungen abmelden (z. B. beim Debuggen)
const registrations = await navigator.serviceWorker.getRegistrations();
const results = await Promise.all(registrations.map((r) => r.unregister()));
console.log(`${results.filter(Boolean).length} Service Worker abgemeldet`);
// Wichtig · Fallstricke
- Sicherer Kontext erforderlich:
navigator.serviceWorkergibt es nur unter HTTPS bzw.localhost. Im privaten Modus von Firefox und in manchen eingebetteten WebViews ist es nicht verfügbar – daher immer mit'serviceWorker' in navigatorprüfen. controllerist beim ersten Besuchnull: Ein neu installierter Worker steuert die Seite erst nach dem Neuladen, außer er ruftclients.claim()auf. Auch nach einem harten Neuladen (Umschalt+F5) bleibtcontrollernull.readywird nie abgelehnt: Schlägt die Registrierung fehl oder passt kein Scope, bleibt das Promise ewig offen – nicht ohne Zeitlimit darauf warten.- Scope-Einschränkung: Ein Skript unter
/js/sw.jskann standardmäßig nur/js/steuern. Für einen größeren Scope muss der Server den HeaderService-Worker-Allowedsenden, oder man legt das Skript ins Wurzelverzeichnis. - Nachrichten-Zwischenspeicher:
message-Events werden gepuffert, bisstartMessages()aufgerufen oderonmessagegesetzt wird. MitaddEventListenerallein muss man ggf.startMessages()manuell aufrufen. - Sicherheit: Ein Service Worker kann alle Anfragen im Scope abfangen und verändern. Das Skript nur aus vertrauenswürdiger Quelle ausliefern,
updateViaCache: 'none'oder kurze Cache-Zeiten nutzen, damit fehlerhafte Versionen schnell ersetzt werden. Die Optiontype: 'module'wird in Firefox erst ab Version 114 unterstützt.