Signatur
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 perpostMessage()Nachrichten zu schicken, z. B. „Neue Version verfügbar“. - Einzelnen Client finden:
clients.get(id)liefert einen bestimmten Client, zum Beispiel anhand vonevent.clientIdin einemfetch-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
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));
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})`);
}
})());
});
// Wichtig · Fallstricke
- Nur im Service Worker verfügbar: Im Hauptthread gibt es
self.clientsnicht. Dort verwendet mannavigator.serviceWorker. - Standardmäßig nur kontrollierte Clients:
matchAll()liefert ohneincludeUncontrolled: truenur Seiten, die dieser Service Worker bereits steuert. Direkt nach der ersten Installation ist die Liste deshalb oft leer. openWindow()undfocus()sind nur als Reaktion auf eine Nutzerinteraktion erlaubt, typischerweise imnotificationclick-Handler. Sonst wird das Promise mit einemInvalidAccessErrorabgelehnt.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).