Start · Sprachen · JavaScript · Referenz · ServiceWorkerGlobalScope: cookiechange

ServiceWorkerGlobalScope: cookiechange

Ereignis

Wird im Service Worker ausgelöst, wenn sich ein Cookie ändert, das zu einem über <code>registration.cookies.subscribe()</code> angelegten Abonnement passt.

seit JavaScript Chromium 87+ (Chrome, Edge, Opera); in Firefox und Kategorie: webapi

Signatur

self.addEventListener("cookiechange", (event: ExtendableCookieChangeEvent) =&gt; void)

Beschreibung

Das cookiechange-Ereignis gehört zur Cookie Store API. Es wird im globalen Bereich eines Service Workers (ServiceWorkerGlobalScope) ausgelöst, sobald ein Cookie gesetzt, geändert oder gelöscht wird, das zu einem Eintrag in der Abonnementliste des Service Workers passt. So kann ein Service Worker auf Anmelde- und Abmeldevorgänge, ablaufende Sitzungs-Cookies oder Einwilligungs-Cookies reagieren, auch wenn gerade keine Seite geöffnet ist.

Anders als in Fenstern (dort gibt es cookieStore.onchange) bekommt ein Service Worker Cookie-Ereignisse nur für abonnierte Cookies. Die Abonnements legt man über CookieStoreManager.subscribe() an, erreichbar über self.registration.cookies im Worker oder registration.cookies auf der Seite. Üblich ist das im install- oder activate-Ereignis. Jedes Abonnement enthält einen name (optional) und eine url, die im Geltungsbereich (Scope) des Service Workers liegen muss.

Der Handler bekommt ein ExtendableCookieChangeEvent. Seine Eigenschaft changed enthält die gesetzten oder geänderten Cookies, deleted die gelöschten bzw. abgelaufenen. Weil das Ereignis von ExtendableEvent erbt, kann man mit event.waitUntil() den Worker aktiv halten, bis asynchrone Aufgaben erledigt sind, zum Beispiel ein Cache-Abgleich oder eine Nachricht an die Clients.

Man registriert den Handler mit self.addEventListener("cookiechange", handler) oder über die Eigenschaft self.oncookiechange = handler. Das Ereignis lässt sich nicht abbrechen und steigt nicht auf (kein Bubbling).

Parameter

Name Typ Default Beschreibung
$event Pflicht ExtendableCookieChangeEvent Das Ereignisobjekt. event.changed ist ein Array von CookieListItem-Objekten für gesetzte oder geänderte Cookies (name, value, domain, path, expires, secure, sameSite, partitioned). event.deleted enthält die gelöschten Cookies. Dazu kommt event.waitUntil(promise).

Rückgabewert

Typ
void
Beschreibung
Der Handler gibt nichts zurück. Asynchrone Arbeit meldet man über event.waitUntil() an.

Beispiele

Abonnement bei der Aktivierung anlegen und auf Änderungen reagieren

// sw.js
self.addEventListener("activate", (event) => {
  event.waitUntil(
    self.registration.cookies.subscribe([
      { name: "session_id", url: "/" }
    ])
  );
});

self.addEventListener("cookiechange", (event) => {
  for (const cookie of event.changed) {
    console.log(`Gesetzt: ${cookie.name} = ${cookie.value}`);
  }
  for (const cookie of event.deleted) {
    console.log(`Gelöscht: ${cookie.name}`);
  }
});
Gesetzt: session_id = abc123 Gelöscht: session_id

Beim Abmelden den Cache leeren und die Clients benachrichtigen (on-Property)

// sw.js
self.oncookiechange = (event) => {
  const loggedOut = event.deleted.some((c) => c.name === "session_id");
  if (!loggedOut) return;

  event.waitUntil((async () => {
    await caches.delete("user-data-v1");
    const clients = await self.clients.matchAll({ includeUncontrolled: true });
    for (const client of clients) {
      client.postMessage({ type: "LOGGED_OUT" });
    }
  })());
};

Abonnements prüfen und wieder entfernen

// Auf der Seite (z. B. main.js)
const registration = await navigator.serviceWorker.ready;

if ("cookies" in registration) {
  const subs = await registration.cookies.getSubscriptions();
  console.log("Aktive Abonnements:", subs);

  // Abonnement entfernen: danach löst der SW kein cookiechange mehr aus
  await registration.cookies.unsubscribe([
    { name: "session_id", url: "/" }
  ]);
} else {
  console.log("Cookie Store API im Service Worker nicht unterstützt");
}
Aktive Abonnements: [{ name: "session_id", url: "https://example.com/" }]

// Wichtig · Fallstricke

  • Ohne Abonnement kein Ereignis: Hat der Service Worker keine Cookies über registration.cookies.subscribe() abonniert, wird cookiechange nie ausgelöst. Die Abonnements bleiben an die Registrierung gebunden und werden beim Abmelden des Service Workers gelöscht.
  • Einschränkung auf den Scope: Die url eines Abonnements muss im Geltungsbereich des Service Workers liegen, sonst wird das Promise von subscribe() mit einem TypeError abgelehnt.
  • HttpOnly-Cookies: Die Cookie Store API sieht keine HttpOnly-Cookies. Deren Änderungen lösen also kein Ereignis aus, und ihre Werte sind nicht lesbar.
  • Nur sichere Kontexte: Die API funktioniert nur über HTTPS (oder localhost).
  • Browser-Kompatibilität: Chromium-basierte Browser unterstützen die API seit Version 87. Firefox und Safari haben die Cookie Store API erst vor Kurzem und nur teilweise eingeführt, cookiechange im Service Worker samt registration.cookies fehlt dort bisher bzw. ist nicht verlässlich. Deshalb vorher prüfen: "cookies" in registration bzw. "oncookiechange" in self.
  • Lebensdauer: Asynchrone Aufgaben immer in event.waitUntil() einhüllen, sonst kann der Browser den Worker vorher beenden.
  • Nicht verwechseln mit dem change-Ereignis von CookieStore in Fenstern: Dort gibt es ein CookieChangeEvent, und man braucht kein Abonnement.