Signatur
Beschreibung
Die schreibgeschützte Eigenschaft url eines Client-Objekts gibt die aktuelle URL des Clients zurück, also des Dokuments bzw. Workers, der vom Service Worker kontrolliert wird oder in seinem Scope liegt. Der Wert ist ein vollständiger, absoluter URL-String (inklusive Pfad, Query-String und Fragment).
Gebraucht wird die Eigenschaft vor allem im Service Worker, wenn man über clients.matchAll() alle offenen Clients bekommt und einen bestimmten auswählen will. Typische Fälle: nach einem Klick auf eine Push-Benachrichtigung prüfen, ob schon ein Tab mit der Ziel-URL offen ist, und diesen fokussieren statt ein neues Fenster zu öffnen. Oder Nachrichten nur an Clients schicken, die auf einer bestimmten Seite sind.
Die URL ist eine Momentaufnahme zum Zeitpunkt, an dem das Client-Objekt erzeugt wurde. Navigiert der Client danach (zum Beispiel per History-API), stimmt der Wert unter Umständen nicht mehr. Wenn es auf Aktualität ankommt, sollte man die Clients neu abfragen.
Rückgabewert
"https://example.com/app/inbox?id=4".Beispiele
Alle Client-URLs im Service Worker auflisten
// sw.js
self.addEventListener('message', async (event) => {
if (event.data === 'list-clients') {
const allClients = await self.clients.matchAll({ includeUncontrolled: true, type: 'all' });
for (const client of allClients) {
console.log(client.type, client.url);
}
}
});
Bei Klick auf eine Benachrichtigung einen vorhandenen Tab fokussieren
// sw.js
self.addEventListener('notificationclick', (event) => {
event.notification.close();
const targetUrl = new URL('/app/inbox', self.location.origin).href;
event.waitUntil((async () => {
const windows = await self.clients.matchAll({ type: 'window', includeUncontrolled: true });
// Tab mit passender URL suchen
const existing = windows.find((c) => c.url === targetUrl);
if (existing) {
return existing.focus();
}
return self.clients.openWindow(targetUrl);
})());
});
Nachricht nur an Clients auf einem bestimmten Pfad senden
// sw.js
const notifyDashboardClients = async (payload) => {
const windows = await self.clients.matchAll({ type: 'window' });
windows
.filter((c) => new URL(c.url).pathname.startsWith('/dashboard'))
.forEach((c) => c.postMessage({ type: 'update', payload }));
};
self.addEventListener('push', (event) => {
event.waitUntil(notifyDashboardClients(event.data?.json() ?? {}));
});
// Wichtig · Fallstricke
- Exakter Vergleich:
client.urlenthält Query-String und Fragment (#…). Ein direkter Vergleich mit===schlägt deshalb schnell fehl. Besser: mitnew URL(client.url)parsen undpathnameoderoriginvergleichen. - Momentaufnahme: Der Wert wird nicht automatisch aktualisiert, wenn der Client weiter navigiert. Hole die Clients bei Bedarf mit
clients.matchAll()oderclients.get(id)neu ab. - Nur im Service Worker:
Client-Objekte gibt es nur im Service-Worker-Kontext (self.clients). Im Fenster-Kontext steht die API nicht zur Verfügung. - Gleicher Ursprung: Es werden nur Clients mit demselben Ursprung wie der Service Worker geliefert. Nicht kontrollierte Clients bekommt man nur mit
includeUncontrolled: true. - Kompatibilität: Wird von allen modernen Browsern unterstützt (Chrome, Edge, Firefox, Safari 11.1+). Service Worker brauchen HTTPS oder
localhost.