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

Clients.openWindow()

Methode

Öffnet aus einem Service Worker heraus ein neues Fenster bzw. einen Tab mit der angegebenen URL und liefert ein Promise auf den zugehörigen <code>WindowClient</code>.

seit JavaScript Baseline: Chrome 40+, Firefox 45+, Safari 16.4+ (n Kategorie: webapi

Signatur

Clients.prototype.openWindow(url)

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

Typ
Promise<WindowClient | null>
Beschreibung
Promise, das mit einem 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);
    }
  })());
});
Geöffnet: https://example.com/chat?id=42

// Wichtig · Fallstricke

  • Nur mit Nutzeraktivierung: Außerhalb von notificationclick, etwa in push, message oder fetch, schlägt der Aufruf meist mit InvalidAccessError fehl. Das Zeitfenster nach dem Klick ist kurz. Rufen Sie openWindow() deshalb möglichst früh auf und nicht erst nach langen await-Ketten.
  • Immer event.waitUntil() verwenden: Sonst kann der Browser den Service Worker beenden, bevor sich das Fenster öffnet.
  • Cross-Origin gibt null zurück: Prüfen Sie den Rückgabewert, bevor Sie focus(), navigate() oder postMessage() aufrufen.
  • Der zurückgegebene WindowClient kann schon erfüllt sein, bevor die Seite vollständig geladen ist. Nachrichten an ihn können verloren gehen, wenn die Seite noch keinen message-Listener registriert hat. Robuster ist es, wenn die Seite sich selbst beim Service Worker meldet.
  • Kompatibilität: Nur im ServiceWorkerGlobalScope verfü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.