Signatur
Beschreibung
Die Methode openWindow() des Interfaces Clients (erreichbar über self.clients im Service Worker) erzeugt einen neuen Browsing-Kontext der obersten Ebene, also ein neues Fenster oder einen neuen Tab, und lädt darin die angegebene URL. Das zurückgegebene Promise wird mit einem WindowClient erfüllt, über den man das Fenster anschließend fokussieren, navigieren oder per postMessage() ansprechen kann.
Der typische Einsatzfall ist das Ereignis notificationclick: Klickt jemand auf eine Push-Benachrichtigung, soll die passende Seite der Web-App geöffnet werden. Üblich ist dabei, zuerst mit clients.matchAll() zu prüfen, ob bereits ein passendes Fenster offen ist, und dieses mit focus() in den Vordergrund zu holen. Nur wenn keins offen ist, ruft man openWindow() auf.
Weil sich Fenster ohne Zutun der Nutzenden nicht öffnen dürfen, ist der Aufruf nur mit vorübergehender Nutzeraktivierung erlaubt. In der Praxis heißt das: Er muss innerhalb eines notificationclick-Handlers erfolgen, und zwar kurz nach dem Klick. Fehlt diese Berechtigung, wird das Promise mit einer InvalidAccessError-DOMException abgelehnt.
Ist die URL same-origin zum Service Worker, wird das Promise mit einem WindowClient erfüllt. Bei einer Cross-Origin-URL öffnet der Browser das Fenster zwar, erfüllt das Promise aber mit null, weil der Service Worker diesen Client nicht steuern darf.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $url Pflicht | string | URL, die im neuen Fenster geladen werden soll. Relative URLs werden relativ zum Skript-Standort des Service Workers aufgelöst. Muss eine gültige URL sein, sonst wird das Promise mit einem TypeError abgelehnt. Auch about:blank führt zu einem TypeError. |
Rückgabewert
WindowClient erfüllt wird, wenn die URL same-origin ist. Bei einer Cross-Origin-URL ist der Wert null. Abgelehnt wird das Promise mit TypeError (ungültige URL oder about:blank) bzw. mit InvalidAccessError (keine Nutzeraktivierung).Beispiele
Seite beim Klick auf eine Benachrichtigung öffnen
// sw.js
self.addEventListener('notificationclick', (event) => {
event.notification.close();
const ziel = event.notification.data?.url ?? '/';
// waitUntil hält den Service Worker aktiv, bis das Fenster offen ist
event.waitUntil(clients.openWindow(ziel));
});
Vorhandenes Fenster fokussieren, sonst neues öffnen
// sw.js
self.addEventListener('notificationclick', (event) => {
event.notification.close();
const zielUrl = new URL('/nachrichten', self.location.origin).href;
event.waitUntil((async () => {
const fenster = await clients.matchAll({
type: 'window',
includeUncontrolled: true
});
const offen = fenster.find((c) => c.url === zielUrl);
if (offen) {
return offen.focus();
}
return clients.openWindow(zielUrl);
})());
});
Mit dem neu geöffneten Fenster kommunizieren und Fehler behandeln
// sw.js
self.addEventListener('notificationclick', (event) => {
event.notification.close();
event.waitUntil((async () => {
try {
const client = await clients.openWindow('/chat?id=42');
if (client === null) {
console.log('Cross-Origin-Fenster: kein Zugriff auf den Client');
return;
}
console.log('Geöffnet:', client.url);
client.postMessage({ typ: 'chat-oeffnen', id: 42 });
} catch (err) {
// z. B. InvalidAccessError ohne Nutzeraktivierung
console.error(err.name, err.message);
}
})());
});
// Wichtig · Fallstricke
- Nur mit Nutzeraktivierung: Außerhalb von
notificationclick, etwa inpush,messageoderfetch, schlägt der Aufruf meist mitInvalidAccessErrorfehl. Das Zeitfenster nach dem Klick ist kurz. Rufen SieopenWindow()deshalb möglichst früh auf und nicht erst nach langenawait-Ketten. - Immer
event.waitUntil()verwenden: Sonst kann der Browser den Service Worker beenden, bevor sich das Fenster öffnet. - Cross-Origin gibt
nullzurück: Prüfen Sie den Rückgabewert, bevor Siefocus(),navigate()oderpostMessage()aufrufen. - Der zurückgegebene
WindowClientkann schon erfüllt sein, bevor die Seite vollständig geladen ist. Nachrichten an ihn können verloren gehen, wenn die Seite noch keinenmessage-Listener registriert hat. Robuster ist es, wenn die Seite sich selbst beim Service Worker meldet. - Kompatibilität: Nur im
ServiceWorkerGlobalScopeverfügbar und nur in sicheren Kontexten (HTTPS). Auf mobilen Plattformen öffnet sich je nach Browser ein Tab oder die installierte PWA. Safari unterstützt Web-Push und damit diesen Ablauf erst ab 16.4. Unter iOS gilt das nur für Web-Apps, die zum Home-Bildschirm hinzugefügt wurden. - Die Methode ist nicht dasselbe wie
window.open(): Es gibt keine Parameter für Fenstername oder Fenstermerkmale.