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

Clients.matchAll()

Methode

Liefert ein Promise, das mit einem Array von <code>Client</code>-Objekten erfüllt wird, die vom aktuellen Service Worker kontrolliert werden oder zu seinem Scope gehören.

seit JavaScript Baseline: alle modernen Browser (Service Worker) Kategorie: webapi

Signatur

Clients.prototype.matchAll(options)

Beschreibung

clients.matchAll() ist nur im Kontext eines Service Workers verfügbar (self.clients) und gibt alle passenden Clients zurück, also Fenster und Tabs, Worker und Shared Worker, die zum Ursprung bzw. Scope des Service Workers gehören. Das Ergebnis ist ein Array von Client- bzw. WindowClient-Objekten.

Typische Einsatzfälle sind:

  • Broadcast-Nachrichten an alle offenen Tabs per client.postMessage(), z. B. „Neue Version verfügbar“.
  • Fokussieren eines schon offenen Fensters nach einem Klick auf eine Push-Benachrichtigung (notificationclick), statt ein neues zu öffnen.
  • Zählen oder Auswerten der aktiven Tabs, etwa um ein Update erst dann anzuwenden, wenn nur noch ein Tab offen ist.

Ohne Optionen liefert die Methode nur Fenster-Clients, die dieser Service Worker aktuell kontrolliert. Mit includeUncontrolled: true kommen auch Clients desselben Ursprungs dazu, die (noch) nicht kontrolliert werden. Das ist z. B. direkt nach der ersten Installation wichtig, bevor clients.claim() aufgerufen wurde. Über type lässt sich der Client-Typ filtern.

Die zurückgegebenen Fenster-Clients sind nach der Reihenfolge ihres letzten Fokus sortiert: Der zuletzt fokussierte Client steht vorne.

Rückgabewert

Typ
Promise<Array<Client | WindowClient>>
Beschreibung
Ein Promise, das mit einem (eventuell leeren) Array von Client-Objekten erfüllt wird. Fenster-Clients sind WindowClient-Instanzen mit focus(), navigate(), focused und visibilityState.

Beispiele

Nachricht an alle offenen Tabs senden

// 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(`${count} Tab(s) benachrichtigt`))
  );
});
3 Tab(s) benachrichtigt

Offenes Fenster nach Klick auf eine Benachrichtigung fokussieren

// 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
    });
    // Gibt es schon einen Tab mit der Ziel-URL? Dann fokussieren
    const existing = windows.find((c) => c.url === targetUrl);
    if (existing) {
      return existing.focus();
    }
    // Sonst ein neues Fenster öffnen
    return self.clients.openWindow(targetUrl);
  })());
});

Offene Clients nach Typ auflisten

// sw.js – z. B. zur Fehlersuche im message-Handler
self.addEventListener('message', async (event) => {
  if (event.data !== 'LIST_CLIENTS') return;
  const all = await self.clients.matchAll({ type: 'all', includeUncontrolled: true });
  const summary = all.map(({ id, type, url }) => ({ id, type, url }));
  console.table(summary);
  event.source.postMessage({ type: 'CLIENTS', summary });
});
┌─────────┬──────────────┬──────────┬──────────────────────────────┐ │ (index) │ id │ type │ url │ │ 0 │ 'a1b2…' │ 'window' │ 'https://example.com/' │ │ 1 │ 'c3d4…' │ 'worker' │ 'https://example.com/w.js' │ └─────────┴──────────────┴──────────┴──────────────────────────────┘

// Wichtig · Fallstricke

  • Nur im Service Worker verfügbar: clients gibt es nur im ServiceWorkerGlobalScope, nicht im Fenster. Service Worker brauchen außerdem einen sicheren Kontext (HTTPS oder localhost).
  • Leeres Array nach der ersten Installation: Direkt nach der Erstregistrierung kontrolliert der Service Worker noch keine Seite. Ohne includeUncontrolled: true oder einen vorherigen Aufruf von clients.claim() ist das Ergebnis deshalb leer.
  • Standardwert von type ist "window": Dedicated und Shared Worker tauchen nur mit type: "worker", "sharedworker" oder "all" auf.
  • Momentaufnahme: Das Array bildet den Zustand zum Zeitpunkt des Aufrufs ab. Clients können danach geschlossen werden, postMessage() an einen schon geschlossenen Client geht dann einfach verloren.
  • waitUntil verwenden: Asynchrone Aufrufe in Event-Handlern (activate, push, notificationclick) in event.waitUntil() einpacken. Sonst kann der Browser den Service Worker vorher beenden.
  • focus() und openWindow() funktionieren nur während einer Benutzerinteraktion, z. B. in notificationclick.
  • Kompatibilität: Wird von allen aktuellen Browsern unterstützt (Chrome, Edge, Firefox, Safari ab 11.1). Auf ältere Safari-Versionen ist bei der Sortierung nach Fokus kein Verlass.