Dostęp asynchroniczny do plików cookie HTTP

Victor Costan

Co to jest interfejs Cookie Store API?

Cookie Store API udostępnia pliki cookie HTTP mechanizmom service worker i zapewnia asynchroniczną alternatywę dla metody document.cookie. Interfejs API ułatwia:

  • Unikaj zacinania się w wątku głównym dzięki asynchronicznego dostępu do plików cookie.
  • Unikaj sondowania w poszukiwaniu plików cookie, ponieważ można zaobserwować ich zmiany.
  • Dostęp do plików cookie z skryptów service worker.

Przeczytaj wyjaśnienie

Obecny stan,

Step Stan
1. Utwórz wyjaśnienie Zakończono
2. Utwórz wstępną wersję roboczą specyfikacji Zakończono
**3. Zbieranie opinii i powtarzanie specyfikacji** **W toku**
4. Testowanie origin Wstrzymano
5. Uruchom Nie rozpoczęto

Jak korzystać z magazynu asynchronicznych plików cookie?

Włącz wersję próbną origin

Aby wypróbować tę funkcję lokalnie, możesz włączyć interfejs API w wierszu poleceń:

chrome --enable-blink-features=CookieStore

Przekazywanie tej flagi w wierszu poleceń włącza interfejs API globalnie w Chrome w bieżącej sesji.

Możesz też włączyć flagę #enable-experimental-web-platform-features w chrome://flags.

Prawdopodobnie nie potrzebujesz plików cookie

Przed przejściem do nowego interfejsu API chcę wspomnieć, że pliki cookie to nadal najgorsza na platformie internetowej podstawowa funkcja przechowywania danych po stronie klienta i nadal należy z nich korzystać w ostateczności. To nie przypadek – pliki cookie były pierwszym mechanizmem przechowywania danych po stronie klienta w internecie. Od tamtej pory dużo się nauczyliśmy.

Oto główne powody, dla których należy unikać plików cookie:

  • Pliki cookie przenoszą schemat pamięci do interfejsu API backendu. Każde żądanie HTTP zawiera migawkę kontenera plików cookie. Ułatwia to inżynierom backendowym wprowadzanie zależności od obecnego formatu plików cookie. Gdy to nastąpi, interfejs nie może zmienić swojego schematu pamięci masowej bez wdrożenia odpowiedniej zmiany w backendzie.

  • Pliki cookie mają złożony model zabezpieczeń. Funkcje nowoczesnych platform internetowych opierają się na tych samych zasadach dotyczących źródła, co oznacza, że każda aplikacja otrzymuje własną piaskownicę i jest całkowicie niezależna od innych aplikacji uruchamianych przez użytkownika. Zakresy plików cookie znacznie zwiększają złożoność artykułu o zabezpieczeniach i próbują tylko podsumować treść tego artykułu.

  • Pliki cookie wiążą się z wysokimi kosztami wydajności. W każdym żądaniu HTTP przeglądarki muszą umieszczać zrzut plików cookie, więc każda zmiana w plikach cookie musi zostać przeprowadzona w stosach pamięci i sieci. Nowoczesne przeglądarki mają wysoce zoptymalizowane przechowywanie plików cookie, ale nigdy nie będą w stanie tworzyć plików cookie tak wydajnych jak inne mechanizmy przechowywania, które nie muszą komunikować się ze stosem sieciowym.

Z powyższych powodów nowoczesne aplikacje internetowe powinny unikać plików cookie i zapisywać identyfikator sesji w IndexedDB oraz dodawać go do nagłówka lub treści za pomocą interfejsu API fetch.

W dalszym ciągu czytasz ten artykuł, ponieważ masz dobry powód, by używać plików cookie...

Uznany interfejs API document.cookie to stuprocentowo gwarantowane źródło zacinania się dla Twojej aplikacji. Na przykład, gdy używasz metody pobierającej document.cookie, przeglądarka musi zatrzymać wykonywanie kodu JavaScript, dopóki nie uzyska żądanych informacji o plikach cookie. Może to spowodować przeskok procesu lub odczyt dysku, co spowoduje zacinanie się interfejsu użytkownika.

Prostym rozwiązaniem tego problemu jest przełączenie się z metody pobierania document.cookie na asynchroniczny interfejs Cookie Store API.

await cookieStore.get('session_id');

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

Metoda ustawiająca document.cookie można zastąpić w podobny sposób. Pamiętaj, że zmiana jest gwarantowana dopiero po rozwiązaniu obietnicy zwróconej przez cookieStore.set.

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

// undefined

Obserwuj, nie ankietuj

Popularna aplikacja do uzyskiwania dostępu do plików cookie przez JavaScript wykrywa, kiedy użytkownik się wylogowuje, i aktualizuje interfejs. Obecnie odbywa się to przez odpytywanie document.cookie, które wprowadza zacinanie i ma negatywny wpływ na żywotność baterii.

Interfejs Cookie Store API udostępnia alternatywną metodę śledzenia zmian w plikach cookie, która nie wymaga odpytywania.

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);
  }
});

Powitanie skryptu service worker

Ze względu na konstrukcję synchroniczną interfejs API document.cookie nie został udostępniony skryptom service worker. Interfejs Cookie Store API jest asynchroniczny i dlatego jest dozwolony w mechanizmach Service Worker.

Interakcja z plikami cookie działa w taki sam sposób w kontekstach dokumentów i w skryptach service worker.

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

Obserwowanie zmian plików cookie wygląda jednak nieco inaczej w przypadku mechanizmów Service Worker. Wybudzenie skryptu service worker może być dość kosztowne, dlatego musimy wyraźnie opisać zmiany w plikach cookie, które interesują go dla tej instancji.

W poniższym przykładzie aplikacja, która korzysta z IndexedDB do buforowania danych użytkownika, monitoruje zmiany w pliku cookie sesji i odrzuca dane z pamięci podręcznej po wylogowaniu się użytkownika.

// 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;
    }
  }
});

Sprawdzone metody

Już wkrótce.

Prześlij opinię

Jeśli wypróbujesz ten interfejs API, daj nam znać, co o nim myślisz. Skieruj opinie na temat kształtu interfejsu API do repozytorium specyfikacji i zgłoś błędy wdrożenia do komponentu Blink>Storage>CookiesAPI Blink.

Szczególnie interesują nas pomiary skuteczności i przypadki użycia wykraczające poza te podane w objaśnieniu.

Dodatkowe zasoby