Асинхронный доступ к файлам cookie HTTP

Victor Costan

Что такое API магазина файлов cookie?

API хранилища файлов cookie предоставляет HTTP-файлы cookie сервисным работникам и предлагает асинхронную альтернативу document.cookie . API упрощает:

  • Избегайте зависаний в основном потоке за счет асинхронного доступа к файлам cookie.
  • Избегайте опроса файлов cookie, поскольку можно наблюдать изменения в файлах cookie.
  • Доступ к файлам cookie сервисных работников.

Читать пояснение

Текущее состояние

Шаг Положение дел
1. Создайте объяснитель Полный
2. Создайте первоначальный проект спецификации. Полный
**3. Собирайте отзывы и вносите изменения в спецификации** **В ходе выполнения**
4. Пробная версия происхождения Приостановлено
5. Запуск Не начался

Как использовать асинхронное хранилище файлов cookie?

Включить пробную версию Origin

Чтобы опробовать его локально, API можно включить в командной строке:

chrome --enable-blink-features=CookieStore

Передача этого флага в командной строке включает API глобально в Chrome для текущего сеанса.

Кроме того, вы можете включить флаг #enable-experimental-web-platform-features в chrome://flags .

Вам (вероятно) не нужны файлы cookie

Прежде чем погрузиться в новый API, я хотел бы заявить, что файлы cookie по-прежнему являются худшим примитивом хранения на стороне клиента веб-платформы, и их все равно следует использовать в крайнем случае. Это не случайность: файлы cookie были первым механизмом хранения данных на стороне клиента в Интернете, и с тех пор мы многому научились.

Основными причинами отказа от файлов cookie являются:

  • Файлы cookie переносят вашу схему хранения в ваш внутренний API. Каждый HTTP-запрос содержит снимок файла cookie. Это позволяет серверным инженерам легко вводить зависимости от текущего формата файлов cookie. Как только это произойдет, ваш интерфейс не сможет изменить свою схему хранения без развертывания соответствующего изменения на серверной части.

  • Файлы cookie имеют сложную модель безопасности. Функции современной веб-платформы следуют одной и той же политике происхождения, что означает, что каждое приложение получает свою собственную изолированную программную среду и полностью независимо от других приложений, которые может запускать пользователь. Области применения файлов cookie значительно усложняют историю безопасности, и простая попытка суммировать это удвоит размер этой статьи.

  • Файлы cookie имеют высокие затраты на производительность. Браузеры должны включать снимок ваших файлов cookie в каждый HTTP-запрос, поэтому каждое изменение файлов cookie должно распространяться по стекам хранилища и сети. Современные браузеры имеют высокооптимизированную реализацию хранилища файлов cookie, но мы никогда не сможем сделать файлы cookie такими же эффективными, как другие механизмы хранения, которым не требуется взаимодействие с сетевым стеком.

По всем вышеизложенным причинам современные веб-приложения должны избегать файлов cookie и вместо этого хранить идентификатор сеанса в IndexedDB и явно добавлять идентификатор в заголовок или тело определенных HTTP-запросов через API выборки .

При этом вы все еще читаете эту статью, потому что у вас есть веская причина использовать файлы cookie...

Почтенный API document.cookie — гарантированный источник мусора для вашего приложения. Например, всякий раз, когда вы используете метод получения document.cookie , браузер должен прекратить выполнение JavaScript до тех пор, пока не получит запрошенную вами информацию о файлах cookie. Это может потребовать перехода процесса или чтения диска и привести к зависанию пользовательского интерфейса.

Простое решение этой проблемы — переключение с метода получения document.cookie на асинхронный API хранилища файлов cookie.

await cookieStore.get('session_id');

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

Установщик document.cookie можно заменить аналогичным образом. Имейте в виду, что изменение гарантированно будет применено только после того, как будет выполнено обещание, возвращенное cookieStore.set .

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

// undefined

Наблюдайте, а не голосуйте

Популярное приложение для доступа к файлам cookie из JavaScript определяет, когда пользователь выходит из системы, и обновляет пользовательский интерфейс. В настоящее время это делается путем опроса document.cookie , что приводит к зависаниям и отрицательно влияет на срок службы батареи.

API хранилища файлов cookie предоставляет альтернативный метод наблюдения за изменениями файлов cookie, не требующий опроса.

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

Приветствуем работников сферы обслуживания

Из-за синхронного дизайна API document.cookie недоступен для сервисных работников . API хранилища файлов cookie является асинхронным и поэтому разрешен в сервисных работниках.

Взаимодействие с файлами cookie работает одинаково в контекстах документов и в сервис-воркерах.

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

Однако наблюдение за изменениями файлов cookie у сервис-воркеров немного отличается. Пробуждение сервис-воркера может оказаться довольно дорогостоящим, поэтому нам приходится явно описывать изменения файлов cookie, которые интересуют работника.

В приведенном ниже примере приложение, которое использует IndexedDB для кэширования пользовательских данных, отслеживает изменения в файле cookie сеанса и удаляет кэшированные данные при выходе пользователя из системы.

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

Лучшие практики

Вскоре.

Обратная связь

Если вы попробуете этот API, сообщите нам, что вы думаете! Пожалуйста, направьте отзыв о форме API в репозиторий спецификаций и сообщите об ошибках реализации в компонент Blink>Storage>CookiesAPI Blink.

Нам особенно интересно узнать об измерениях производительности и вариантах использования, выходящих за рамки описанных в пояснении .

Дополнительные ресурсы