Start · Sprachen · JavaScript · Referenz · CookieStore

CookieStore

Schnittstelle

Promise-basierte Schnittstelle der Cookie Store API zum asynchronen Lesen, Setzen und Löschen von Cookies – im Fenster über <code>window.cookieStore</code> und im Service Worker.

seit JavaScript Chrome/Edge 87+, Firefox 140+, Safari 18.4+ (nur s Kategorie: webapi

Signatur

interface CookieStore extends EventTarget

Beschreibung

Das Interface CookieStore ist der moderne, asynchrone Ersatz für das mühsame Parsen und Zusammensetzen von document.cookie. Statt eines einzigen Strings liefert es strukturierte Objekte (name, value, domain, path, expires, secure, sameSite, partitioned). Alle Operationen geben ein Promise zurück und blockieren daher den Hauptthread nicht.

Man erreicht die Instanz über window.cookieStore im Dokument bzw. über self.cookieStore im Service Worker. Weil document dort nicht existiert, ist das die einzige Möglichkeit, aus einem Service Worker heraus Cookies zu lesen oder zu schreiben. Eine eigene Instanz mit new kann nicht erzeugt werden.

Die wichtigsten Methoden:

  • get(name | options) – liefert das erste passende Cookie oder null.
  • getAll(name | options) – liefert ein Array aller passenden Cookies.
  • set(name, value) bzw. set(options) – setzt oder überschreibt ein Cookie.
  • delete(name | options) – löscht ein Cookie (setzt es intern auf abgelaufen).

Zusätzlich löst CookieStore das Ereignis change aus (CookieChangeEvent mit den Arrays changed und deleted), sobald sich Cookies im Gültigkeitsbereich der Seite ändern. Im Service Worker nutzt man dafür stattdessen cookiechange in Verbindung mit registration.cookies.subscribe().

Parameter

Name Typ Default Beschreibung
$name string Für get(), getAll(), delete() und set(name, value): Name des Cookies.
$value string Für set(name, value): Wert des Cookies.
$options.name string Name des Cookies in der Objekt-Variante.
$options.value string Wert des Cookies (nur bei set()).
$options.url string URL des Dokuments Für get()/getAll(): URL, deren Cookies gesucht werden. Im Dokument muss sie der aktuellen URL entsprechen, im Service Worker muss sie in dessen Gültigkeitsbereich liegen.
$options.expires number|null null (Sitzungs-Cookie) Ablaufzeitpunkt als Zeitstempel in Millisekunden (z. B. Date.now() + 86400000).
$options.domain string|null null (nur aktueller Host) Domain, für die das Cookie gilt. Muss zur aktuellen Domain passen.
$options.path string "/" Pfad, für den das Cookie gilt.
$options.sameSite "strict"|"lax"|"none" "strict" SameSite-Richtlinie. Achtung: Standardwert ist strict, nicht lax wie bei document.cookie.
$options.partitioned boolean false Erzeugt ein partitioniertes Cookie (CHIPS), das an den Top-Level-Kontext gebunden ist.

Rückgabewert

Typ
Promise<CookieListItem | null> | Promise<CookieListItem[]> | Promise<undefined>
Beschreibung
get() liefert ein CookieListItem oder null, getAll() ein Array davon, set() und delete() lösen mit undefined auf. Schlägt eine Operation fehl, wird das Promise mit einem TypeError bzw. SecurityError abgelehnt.

Beispiele

Cookie setzen und wieder auslesen

const speichereTheme = async (theme) => {
  await cookieStore.set({
    name: 'theme',
    value: theme,
    expires: Date.now() + 30 * 24 * 60 * 60 * 1000, // 30 Tage
    sameSite: 'lax'
  });

  const cookie = await cookieStore.get('theme');
  console.log(cookie?.value);
};

speichereTheme('dark').catch((err) => console.error('Cookie konnte nicht gesetzt werden:', err));
dark

Alle Cookies auflisten und eines löschen

const aufraeumen = async () => {
  const alle = await cookieStore.getAll();
  console.log(alle.map(({ name, value }) => `${name}=${value}`));

  // Tracking-Cookie entfernen (path/domain müssen zum Setzen passen)
  await cookieStore.delete({ name: 'tracking_id', path: '/' });
  console.log(await cookieStore.get('tracking_id'));
};

aufraeumen();
["theme=dark", "tracking_id=abc123"] null

Auf Cookie-Änderungen reagieren (change-Event)

const onCookieChange = (event) => {
  for (const c of event.changed) console.log('Geändert:', c.name, c.value);
  for (const c of event.deleted) console.log('Gelöscht:', c.name);
};

cookieStore.addEventListener('change', onCookieChange);

// Alternativ: cookieStore.onchange = onCookieChange;

await cookieStore.set('session_hint', 'aktiv');

// Später wieder abmelden
cookieStore.removeEventListener('change', onCookieChange);
Geändert: session_hint aktiv

Cookies im Service Worker lesen und überwachen

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

self.addEventListener('cookiechange', (event) => {
  if (event.deleted.some((c) => c.name === 'auth_token')) {
    console.log('Abgemeldet – Cache wird geleert');
    caches.delete('user-data');
  }
});

self.addEventListener('fetch', (event) => {
  event.respondWith((async () => {
    const token = await self.cookieStore.get('auth_token');
    console.log('Angemeldet:', Boolean(token));
    return fetch(event.request);
  })());
});
Angemeldet: true

// Wichtig · Fallstricke

  • Browser-Kompatibilität: Chromium-Browser seit Version 87, Safari ab 18.4, Firefox erst ab 140 (ohne change-Event im Service Worker in älteren Versionen). Vorher per if ('cookieStore' in self) prüfen und auf document.cookie zurückfallen.
  • Nur in sicheren Kontexten (HTTPS oder localhost) verfügbar. Cookies werden immer mit dem Attribut Secure gesetzt.
  • HttpOnly-Cookies sind unsichtbar und können weder gelesen noch gesetzt werden – das ist gewollt und schützt Sitzungs-Cookies vor XSS. Sensible Tokens gehören weiterhin in serverseitig gesetzte HttpOnly-Cookies.
  • sameSite ist standardmäßig "strict". Wer das gewohnte Verhalten von document.cookie erwartet, muss "lax" explizit angeben.
  • delete() entfernt ein Cookie nur, wenn path, domain und partitioned mit denen beim Setzen übereinstimmen.
  • expires erwartet einen Zeitstempel in Millisekunden (number), kein max-age in Sekunden. Einen Date-String akzeptiert die API nicht zuverlässig.
  • Namen und Werte dürfen keine Steuerzeichen oder ; enthalten, und Name und Wert dürfen zusammen höchstens 4096 Byte lang sein. Sonst wird das Promise mit TypeError abgelehnt.
  • In Drittanbieter-iframes schränken Tracking-Schutz und Speicherpartitionierung den Zugriff ein.