Dostęp asynchroniczny do plików cookie HTTP

Victor Costan

Czym jest interfejs Cookie Store API?

Interfejs Cookie Store API udostępnia pliki cookie HTTP usługom workera i oferuje asynchroniczną alternatywę dla document.cookie. Interfejs API ułatwia:

  • Unikaj zacięć w wątku głównym, uzyskując dostęp do plików cookie asynchronicznie.
  • Unikaj sprawdzania plików cookie, ponieważ zmiany w plikach cookie mogą być widoczne.
  • Dostęp do plików cookie z serwisów worker.

Przeczytaj wyjaśnienie

Obecny stan,

Krok Stan
1. Tworzenie wyjaśnienia Zakończono
2. Tworzenie wstępnej wersji specyfikacji Zakończono
**3. Zbieranie opinii i ulepszanie specyfikacji** **W toku**
4. Wersja próbna origin Wstrzymano
5. Uruchom Nie rozpoczęto

Jak korzystać z asynchronicznego magazynu plików cookie?

Włącz okres próbny punktu początkowego

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

chrome --enable-blink-features=CookieStore

Podanie tej flagi w wierszu poleceń powoduje globalne włączenie interfejsu API w Chrome na czas bieżącej sesji.

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

(Prawdopodobnie) nie potrzebujesz plików cookie

Zanim przejdziemy do nowego interfejsu API, warto pamiętać, że pliki cookie są nadal najgorszym sposobem przechowywania danych po stronie klienta w ramach platformy internetowej i należy używać ich tylko w razie potrzeby. Nie jest to przypadek. Pliki cookie były pierwszym mechanizmem przechowywania po stronie klienta w internecie i od tego czasu wiele się nauczyliśmy.

Główne powody unikania plików cookie to:

  • Pliki cookie przekazują schemat magazynowania do interfejsu API na zapleczu. Każde żądanie HTTP zawiera kopię zapasową pliku cookie. Dzięki temu inżynierowie pracujący nad backendem mogą łatwo wprowadzać zależności od bieżącego formatu plików cookie. Gdy to nastąpi, front-end nie będzie mógł zmienić schematu magazynu bez wdrożenia odpowiedniej zmiany w back-endzie.

  • Pliki cookie mają złożony model zabezpieczeń. Funkcje nowoczesnej platformy internetowej są zgodne z zasadami dotyczącymi tego samego źródła, co oznacza, że każda aplikacja ma własny piaskownicy i jest całkowicie niezależna od innych aplikacji, które użytkownik może uruchamiać. Zakresy działania plików cookie to znacznie bardziej skomplikowana kwestia bezpieczeństwa, a samo podsumowanie tego zagadnienia spowodowałoby podwojenie rozmiaru tego artykułu.

  • Pliki cookie mają wysoki koszt wydajności. Przeglądarki muszą uwzględniać w każdym żądaniu HTTP migawkę plików cookie, więc każda zmiana plików cookie musi być propagowana w warstwach pamięci i sieci. Nowoczesne przeglądarki mają bardzo zoptymalizowane implementacje pamięci cookie, ale nigdy nie będziemy w stanie stworzyć plików cookie tak wydajnych jak inne mechanizmy przechowywania, które nie muszą komunikować się ze stekiem sieciowym.

Z wszystkich powyższych powodów nowoczesne aplikacje internetowe nie powinny używać plików cookie, a zamiast tego powinny przechowywać identyfikator sesji w interfejsie IndexedDB i dodawać go jawnie do nagłówka lub treści określonych żądań HTTP za pomocą interfejsu fetch API.

Mimo to czytasz ten artykuł, ponieważ masz dobry powód, aby używać plików cookie.

Stary interfejs API document.cookie jest prawie zawsze źródłem zakłóceń w aplikacji. Na przykład za każdym razem, gdy używasz funkcji document.cookie getter, przeglądarka musi zatrzymać wykonywanie kodu JavaScriptu, dopóki nie otrzyma żądanych informacji o plikach cookie. Może to wymagać przełączenia procesu lub odczytu z dysku, co spowoduje opóźnienia w interfejsie.

Prostym rozwiązaniem tego problemu jest przejście z gettera 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"
// }

Zmienna document.cookie setter może być zastępowana w podobny sposób. Pamiętaj, że zmiana zostanie zastosowana dopiero po zakończeniu działania obietnicy zwracanej przez funkcję cookieStore.set.

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

// undefined

Obserwuj, nie przeprowadzaj ankiety

Popularnym sposobem uzyskiwania dostępu do plików cookie z JavaScriptu jest wykrywanie, kiedy użytkownik się wyloguje, i aktualizowanie interfejsu użytkownika. Obecnie jest to realizowane przez odczyt zapytańdocument.cookie, co powoduje opóźnienia i ma negatywny wpływ na żywotność baterii.

Interfejs Cookie Store API zapewnia alternatywną metodę obserwowania zmian plików cookie, która nie wymaga sprawdzania.

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

Witamy skrypty service worker

Ze względu na projekt oparty na synchronizacji interfejs document.cookie API nie jest dostępny dla usług działających w tle. Interfejs Cookie Store API jest asynchroniczny, dlatego jest dozwolony w serwisach workers.

Interakcje z plikami cookie działają tak samo w kontekście dokumentów i w przypadku pracowników obsługi.

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

Obserwowanie zmian plików cookie jest jednak w przypadku usług działających w tle nieco inne. Wzbudzanie usługi może być dość kosztowne, dlatego musimy wyraźnie opisać zmiany w plikach cookie, którymi jest zainteresowany pracownik.

W przykładzie poniżej aplikacja, która używa IndexedDB do buforowania danych użytkownika, monitoruje zmiany w pliku cookie sesji i usuwanie danych z bufora po wylogowaniu 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 zdecydujesz się wypróbować ten interfejs API, daj nam znać, co o nim myślisz. Opinie na temat kształtu interfejsu API należy kierować do repozytorium specyfikacji, a błędy implementacji do komponentu Blink: Blink>Storage>CookiesAPI.

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

Dodatkowe materiały