Start · Sprachen · JavaScript · Referenz · ServiceWorkerGlobalScope.clients

ServiceWorkerGlobalScope.clients

Eigenschaft

Schreibgeschützte Eigenschaft, die das <code>Clients</code>-Objekt des Service Workers liefert, über das sich kontrollierte Fenster, Tabs und Worker abfragen und steuern lassen.

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

Signatur

ServiceWorkerGlobalScope.clients

Beschreibung

Die Eigenschaft clients ist nur im globalen Kontext eines Service Workers verfügbar, also als self.clients bzw. einfach clients. Sie gibt ein Clients-Objekt zurück. Damit greift der Service Worker auf alle Clients zu, also auf Fenster, Tabs, iframes sowie Dedicated und Shared Worker desselben Ursprungs.

Typische Aufgaben sind:

  • Clients auflisten: Mit clients.matchAll() erhält man alle kontrollierten Seiten, etwa um ihnen per postMessage() Nachrichten zu schicken, z. B. „Neue Version verfügbar“.
  • Einzelnen Client finden: clients.get(id) liefert einen bestimmten Client, zum Beispiel anhand von event.clientId in einem fetch-Handler.
  • Fenster öffnen: clients.openWindow(url) öffnet nach einem Klick auf eine Push-Benachrichtigung einen neuen Tab.
  • Kontrolle übernehmen: clients.claim() sorgt dafür, dass ein neu aktivierter Service Worker bereits geöffnete Seiten sofort steuert und nicht erst nach dem nächsten Neuladen.

Die Eigenschaft selbst ist schreibgeschützt und nimmt keine Parameter entgegen. Alle Methoden des Clients-Objekts arbeiten asynchron und geben Promises zurück. Im Zusammenspiel mit event.waitUntil() bleibt der Service Worker dadurch aktiv, bis die Operation abgeschlossen ist.

Rückgabewert

Typ
Clients
Beschreibung
Das dem Service Worker zugeordnete Clients-Objekt mit den Methoden get(), matchAll(), openWindow() und claim().

Beispiele

Sofortige Kontrolle nach der Aktivierung mit claim()

// sw.js
self.addEventListener('install', (event) => {
  // Wartephase überspringen
  self.skipWaiting();
});

self.addEventListener('activate', (event) => {
  // Bereits offene Seiten sofort übernehmen
  event.waitUntil(self.clients.claim());
});

Allen offenen Tabs eine Nachricht schicken

// sw.js
const broadcast = async (message) => {
  const allClients = await self.clients.matchAll({
    type: 'window',
    includeUncontrolled: true
  });
  for (const client of allClients) {
    client.postMessage(message);
  }
  return allClients.length;
};

self.addEventListener('activate', (event) => {
  event.waitUntil(
    broadcast({ type: 'SW_UPDATED', version: '2.1.0' })
      .then((count) => console.log(`Nachricht an ${count} Tab(s) gesendet`))
  );
});

// Seite (main.js):
// navigator.serviceWorker.addEventListener('message', (e) => console.log(e.data));
Nachricht an 2 Tab(s) gesendet

Bei Klick auf eine Benachrichtigung Tab fokussieren oder öffnen

// sw.js
self.addEventListener('notificationclick', (event) => {
  event.notification.close();
  const targetUrl = new URL('/nachrichten', self.location.origin).href;

  event.waitUntil((async () => {
    const windows = await self.clients.matchAll({ type: 'window', includeUncontrolled: true });
    const existing = windows.find((c) => c.url === targetUrl);
    if (existing) {
      return existing.focus();
    }
    return self.clients.openWindow(targetUrl);
  })());
});

Anfragenden Client im fetch-Handler ermitteln

// sw.js
self.addEventListener('fetch', (event) => {
  if (!event.clientId) return;

  event.waitUntil((async () => {
    const client = await self.clients.get(event.clientId);
    if (client) {
      console.log(`Anfrage ${event.request.url} von ${client.url} (${client.type})`);
    }
  })());
});
Anfrage https://example.com/api/daten von https://example.com/ (window)

// Wichtig · Fallstricke

  • Nur im Service Worker verfügbar: Im Hauptthread gibt es self.clients nicht. Dort verwendet man navigator.serviceWorker.
  • Standardmäßig nur kontrollierte Clients: matchAll() liefert ohne includeUncontrolled: true nur Seiten, die dieser Service Worker bereits steuert. Direkt nach der ersten Installation ist die Liste deshalb oft leer.
  • openWindow() und focus() sind nur als Reaktion auf eine Nutzerinteraktion erlaubt, typischerweise im notificationclick-Handler. Sonst wird das Promise mit einem InvalidAccessError abgelehnt.
  • claim() mit Bedacht einsetzen: Seiten, die mit einer alten Version geladen wurden, werden dann plötzlich vom neuen Worker gesteuert. Das kann zu inkonsistenten Cache-Zuständen führen.
  • Asynchrone Aufrufe immer in event.waitUntil() einbetten. Sonst kann der Browser den Service Worker vorzeitig beenden.
  • Service Worker funktionieren nur in sicheren Kontexten (HTTPS oder localhost).