Start · Sprachen · JavaScript · Referenz · ServiceWorkerContainer

ServiceWorkerContainer

Schnittstelle

Über <code>navigator.serviceWorker</code> erreichbares Objekt, mit dem man Service Worker registriert, abfragt und mit dem steuernden Worker kommuniziert.

seit JavaScript Baseline: alle modernen Browser (seit 2018) Kategorie: webapi

Signatur

interface ServiceWorkerContainer extends EventTarget

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 ein Promise<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 – der ServiceWorker, der die Seite aktuell steuert, oder null (z. B. nach einem harten Neuladen mit Umschalt-Taste oder beim allerersten Besuch).
  • startMessages() – gibt Nachrichten frühzeitig frei, die per postMessage() 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

Typ
ServiceWorkerContainer
Beschreibung
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);
    }
  });
}
Registriert für Scope: https://example.com/

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);
});
Vom Service Worker: { type: 'CACHED', count: 1 }

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');
Aktueller Controller: https://example.com/sw.js

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`);
1 Service Worker abgemeldet

// Wichtig · Fallstricke

  • Sicherer Kontext erforderlich: navigator.serviceWorker gibt 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 navigator prüfen.
  • controller ist beim ersten Besuch null: Ein neu installierter Worker steuert die Seite erst nach dem Neuladen, außer er ruft clients.claim() auf. Auch nach einem harten Neuladen (Umschalt+F5) bleibt controller null.
  • ready wird 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.js kann standardmäßig nur /js/ steuern. Für einen größeren Scope muss der Server den Header Service-Worker-Allowed senden, oder man legt das Skript ins Wurzelverzeichnis.
  • Nachrichten-Zwischenspeicher: message-Events werden gepuffert, bis startMessages() aufgerufen oder onmessage gesetzt wird. Mit addEventListener allein 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 Option type: 'module' wird in Firefox erst ab Version 114 unterstützt.