Start · Sprachen · JavaScript · Referenz · Clients.claim()

Clients.claim()

Methode

Macht den aktiven Service Worker sofort zum <code>controller</code> aller Clients in seinem Scope, ohne dass die Seiten neu geladen werden müssen.

seit JavaScript Baseline: alle modernen Browser (Chrome 42+, Firef Kategorie: webapi

Signatur

Clients.prototype.claim()

Beschreibung

Wenn ein Service Worker zum ersten Mal registriert wird, steuert er Seiten, die bereits geöffnet sind, nicht automatisch. Erst beim nächsten Laden laufen deren Netzwerkanfragen über den Worker. Mit self.clients.claim() übernimmt der aktive Service Worker die Kontrolle über alle Clients (Fenster, Tabs, Worker) in seinem scope sofort. Deren navigator.serviceWorker.controller wird gesetzt und in jedem betroffenen Client wird das Ereignis controllerchange ausgelöst.

Üblicherweise ruft man claim() im activate-Ereignis auf, eingebettet in event.waitUntil(). Zusammen mit self.skipWaiting() im install-Ereignis sorgt das dafür, dass eine neue Version des Service Workers ohne Wartezeit aktiv wird und alle offenen Tabs übernimmt.

Zu beachten: Die Seiten wurden eventuell mit Ressourcen aus einer älteren Version (oder ganz ohne Service Worker) geladen. Wenn der neue Worker andere Cache-Strategien oder API-Versionen nutzt, kann es zu Inkonsistenzen kommen. Setze claim() daher bewusst ein, wenn die neue Version mit bereits geladenen Seiten verträglich ist.

Rückgabewert

Typ
Promise<undefined>
Beschreibung
Ein Promise, das sich mit undefined erfüllt, sobald der Service Worker alle passenden Clients übernommen hat. Es wird mit einem InvalidStateError (DOMException) abgelehnt, wenn der Worker nicht der aktive Worker seiner Registrierung ist.

Beispiele

Clients direkt beim Aktivieren übernehmen

// sw.js
self.addEventListener('activate', (event) => {
  event.waitUntil(self.clients.claim());
});

Sofortiges Update mit skipWaiting() und claim()

// sw.js
const CACHE = 'app-v2';

self.addEventListener('install', (event) => {
  event.waitUntil(
    caches.open(CACHE)
      .then((cache) => cache.addAll(['/', '/app.js', '/styles.css']))
      .then(() => self.skipWaiting())
  );
});

self.addEventListener('activate', (event) => {
  event.waitUntil((async () => {
    // Alte Caches aufräumen
    const keys = await caches.keys();
    await Promise.all(keys.filter((k) => k !== CACHE).map((k) => caches.delete(k)));
    // Danach alle offenen Tabs übernehmen
    await self.clients.claim();
    console.log('Service Worker steuert jetzt alle Clients');
  })());
});
Service Worker steuert jetzt alle Clients

Übernahme auf der Seite erkennen (controllerchange)

// main.js (Seite)
if ('serviceWorker' in navigator) {
  navigator.serviceWorker.addEventListener('controllerchange', () => {
    console.log('Neuer Controller:', navigator.serviceWorker.controller?.scriptURL);
  });

  await navigator.serviceWorker.register('/sw.js');
  console.log('Gesteuert?', Boolean(navigator.serviceWorker.controller));
}
Gesteuert? false Neuer Controller: https://example.com/sw.js

Alle Clients nach der Übernahme benachrichtigen

// sw.js
self.addEventListener('activate', (event) => {
  event.waitUntil((async () => {
    await self.clients.claim();
    const list = await self.clients.matchAll({ type: 'window' });
    list.forEach((client) => client.postMessage({ type: 'SW_ACTIVATED' }));
  })());
});

// Wichtig · Fallstricke

  • Nur im aktiven Worker: Ein Aufruf in install, also bevor der Worker aktiv ist, führt zu einem abgelehnten Promise mit InvalidStateError. Rufe claim() deshalb in activate oder später auf.
  • Immer mit waitUntil(): Ohne event.waitUntil() kann der Browser den Worker beenden, bevor die Übernahme abgeschlossen ist.
  • Gemischte Versionen: Bereits geladene Seiten laufen danach mit einem Service Worker, der möglicherweise andere Caches oder Routen erwartet. Bei tiefgreifenden Änderungen ist ein Neuladen der Seite, z. B. über controllerchange, oft die sicherere Lösung.
  • Scope: Übernommen werden nur Clients, deren URL im scope der Registrierung liegt und die denselben Ursprung (Origin) haben.
  • Kompatibilität: Wird von allen modernen Browsern unterstützt. Service Worker funktionieren nur in sicheren Kontexten (HTTPS oder localhost). Bei einem Hard-Reload (Shift+Neu laden) umgeht die Seite den Service Worker, und controller bleibt null.