Asynchroner Zugriff auf HTTP-Cookies

Victor Costan

Was ist die Cookie Store API?

Die Cookie Store API stellt HTTP-Cookies für Service Worker bereit und bietet eine asynchrone Alternative zu document.cookie. Die API vereinfacht folgende Aufgaben:

  • Vermeiden Sie Verzögerungen im Hauptthread, indem Sie asynchron auf Cookies zugreifen.
  • Vermeiden Sie das Abfragen von Cookies, da Änderungen an Cookies beobachtet werden können.
  • Auf Cookies von Service Workern zugreifen.

Erklärung lesen

Aktueller Status

Step Status
1. Erklärende Erklärung erstellen Abschließen
2. Ersten Entwurf der Spezifikation erstellen Abschließen
**3. Feedback einholen und Spezifikationen iterieren** **In Bearbeitung**
4. Ursprungstest Pausiert
5. Einführung Nicht gestartet

Wie verwende ich den asynchronen Cookie-Speicher?

Ursprungstest aktivieren

Wenn Sie die API lokal testen möchten, können Sie sie in der Befehlszeile aktivieren:

chrome --enable-blink-features=CookieStore

Wenn Sie dieses Flag in der Befehlszeile übergeben, wird die API für die aktuelle Sitzung global in Chrome aktiviert.

Alternativ können Sie das Flag #enable-experimental-web-platform-features in chrome://flags aktivieren.

Du brauchst wahrscheinlich keine Cookies

Bevor wir uns mit der neuen API befassen, möchte ich anmerken, dass Cookies immer noch die schlechteste clientseitige Speicherprimitive der Webplattform sind und immer noch als letztes Mittel verwendet werden sollten. Dies ist kein Zufall. Cookies waren der erste clientseitige Speichermechanismus des Webs und wir haben seitdem viel gelernt.

Dies sind die Hauptgründe für die Vermeidung von Cookies:

  • Cookies bringen Ihr Speicherschema in Ihre Back-End-API. Jede HTTP-Anfrage enthält einen Snapshot der Cookie-JAR-Datei. Dies erleichtert Back-End-Entwicklern die Einführung von Abhängigkeiten vom aktuellen Cookie-Format. Danach kann das Speicherschema des Front-Ends nicht mehr geändert werden, ohne eine entsprechende Änderung im Back-End bereitzustellen.

  • Cookies haben ein komplexes Sicherheitsmodell. Moderne Webplattformfunktionen folgen derselben Ursprungsrichtlinie. Das bedeutet, dass jede Anwendung eine eigene Sandbox erhält und vollständig unabhängig von anderen Anwendungen ist, die der Nutzer möglicherweise ausführt. Cookie-Bereiche ergeben eine wesentlich komplexere Sicherheitsgeschichte. Mit einer einfachen Zusammenfassung würde sich der Umfang dieses Artikels verdoppeln.

  • Cookies haben hohe Leistungskosten. Browser müssen in jede HTTP-Anfrage einen Snapshot Ihrer Cookies einfügen, sodass jede Cookie-Änderung über den Speicher- und Netzwerk-Stack übertragen werden muss. Moderne Browser haben hochoptimierte Cookiespeicher-Implementierungen, aber wir werden Cookies niemals so effizient gestalten können wie die anderen Speichermechanismen, die nicht mit dem Netzwerk-Stack kommunizieren müssen.

Aus allen oben genannten Gründen sollten moderne Webanwendungen Cookies vermeiden und stattdessen eine Sitzungs-ID in IndexedDB speichern und die ID explizit über die fetch API in den Header oder Text von bestimmten HTTP-Anfragen einfügen.

Sie lesen diesen Artikel aber immer noch, weil Sie einen guten Grund haben, Cookies zu verwenden...

Die altehrwürdige document.cookie API ist eine recht sichere Quelle für Verzögerungen bei Ihrer Anwendung. Wenn Sie beispielsweise den Getter document.cookie verwenden, muss der Browser JavaScript so lange nicht mehr ausführen, bis die angeforderten Cookie-Informationen vorliegen. Dies kann einen Prozess-Hop oder einen Laufwerklesevorgang erfordern und zu Verzögerungen bei der UI führen.

Eine einfache Lösung für dieses Problem ist der Wechsel vom document.cookie-Getter zur asynchronen Cookie Store API.

await cookieStore.get('session_id');

// {
//   domain: "example.com",
//   expires: 1593745721000,
//   name: "session_id",
//   path: "/",
//   sameSite: "unrestricted",
//   secure: true,
//   value: "yxlgco2xtqb.ly25tv3tkb8"
// }

Der document.cookie-Setter kann auf ähnliche Weise ersetzt werden. Beachten Sie, dass die Änderung erst dann garantiert wird, wenn das von cookieStore.set zurückgegebene Promise aufgelöst wird.

await cookieStore.set({name: 'opt_out', value: '1'});

// undefined

Beobachten, nicht abfragen

Eine beliebte Anwendung für den Zugriff auf Cookies über JavaScript ist die Aktualisierung der Benutzeroberfläche und die Erkennung, wann sich ein Nutzer abmeldet. Dazu wird document.cookie abgefragt, was zu Verzögerungen führt und sich negativ auf die Akkulaufzeit auswirkt.

Die Cookie Store API bietet eine alternative Methode zur Beobachtung von Cookie-Änderungen, die kein Abfragen erfordert.

cookieStore.addEventListener('change', event => {
  for (const cookie of event.changed) {
    if (cookie.name === 'session_id') sessionCookieChanged(cookie.value);
  }
  for (const cookie of event.deleted) {
    if (cookie.name === 'session_id') sessionCookieChanged(null);
  }
});

Mitarbeiter im Service willkommen heißen

Aufgrund des synchronen Designs ist die document.cookie API Service Workern noch nicht verfügbar. Die Cookie Store API ist asynchron und daher in Service-Workern zulässig.

Die Interaktion mit Cookies funktioniert in Dokumentkontexten und bei Service Workern gleich.

// Works in documents and service workers.
async function logOut() {
  await cookieStore.delete('session_id');
}

Die Beobachtung von Cookie-Änderungen ist bei Service Workern jedoch ein wenig anders. Das Aktivieren eines Service Workers kann ziemlich teuer sein. Daher müssen wir die Cookie-Änderungen, für die der Worker interessiert ist, explizit beschreiben.

Im folgenden Beispiel überwacht eine Anwendung, die IndexedDB zum Speichern von Nutzerdaten im Cache verwendet, Änderungen am Sitzungscookie und verwirft die im Cache gespeicherten Daten, wenn sich der Nutzer abmeldet.

// Specify the cookie changes we're interested in during the install event.
self.addEventListener('install', event => {
  event.waitUntil(cookieStore.subscribeToChanges([{name: 'session_id'}]));
});

// Delete cached data when the user logs out.
self.addEventListener('cookiechange', event => {
  for (const cookie of event.deleted) {
    if (cookie.name === 'session_id') {
      indexedDB.deleteDatabase('user_cache');
      break;
    }
  }
});

Best Practices

Bald verfügbar.

Feedback

Wenn Sie diese API ausprobieren, würden wir uns über Ihr Feedback freuen! Bitte senden Sie Feedback zur API-Form an das Spezifikations-Repository und melden Sie Implementierungsfehler an die Blink-Komponente Blink>Storage>CookiesAPI.

Uns interessieren besonders die Leistungsmessungen und Anwendungsfälle, die über die in der Erläuterung beschriebenen hinausgehen.

Weitere Ressourcen