Пробная версия Origin для поддержки HTTP-заголовков в Storage Access

Наталья Маркобородова
Natalia Markoborodova

Chrome начинает пробную версию добавления HTTP-заголовков в Storage Access API (SAA) версии 130: Storage Access Headers . Новые заголовки запроса Sec-Fetch-Storage-Access и ответа Activate-Storage-Access предназначены для поддержки ресурсов, отличных от iframe, а также для повышения производительности и удобства использования веб-сайтов, использующих встроенный контент, такой как виджеты социальных сетей, календари и интерактивные инструменты.

Поток JavaScript (и его ограничения)

Ранее SAA требовал вызова JavaScript API document.requestStorageAccess() при каждой перезагрузке, даже если пользователь уже дал разрешение. Несмотря на эффективность, этот метод имеет ограничения:

  • Множественные сетевые циклы передачи данных: процесс часто включал в себя несколько сетевых запросов и перезагрузок страниц, прежде чем встроенный контент мог полноценно функционировать.
  • Зависимость от iframe: выполнение JavaScript требовало использования iframes или подресурсов внутри iframes, что ограничивало гибкость для разработчиков.

Например, виджет календаря из calendar.example , встроенный в website.example с использованием только JavaScript, будет выглядеть следующим образом:

  1. Загрузите плейсхолдер: website.example запрашивает виджет. Поскольку виджет calendar.example , встроенный в website.example , не имеет доступа к своим неразделенным файлам cookie, вместо него отображается плейсхолдер.
  2. Запрос разрешения: загружается заполнитель, а затем вызывает document.requestStorageAccess() для запроса разрешения storage-access .
  3. Пользователь решает предоставить разрешение .
  4. Перезагрузите виджет: Виджет обновится, на этот раз с доступом к cookie-файлам, и, наконец, загрузит персонализированный контент.
  5. Каждый раз, когда пользователь снова посещает сайт, на котором встроен виджет calendar.example , поток выглядит точно так же, как на шагах 1, 2 и 4 ; единственное упрощение заключается в том, что пользователю не нужно повторно предоставлять доступ.

Этот поток неэффективен: если пользователь уже предоставил разрешение на хранение, первоначальная загрузка iframe, вызов document.requestStorageAccess() и последующая перезагрузка становятся ненужными и создают задержку.

Новый поток с заголовками HTTP

Новые заголовки доступа к хранилищу обеспечивают более эффективную загрузку встроенного контента, включая ресурсы, не входящие в iframe.

Благодаря заголовкам доступа к хранилищу браузер автоматически извлекает ресурсы с установленным заголовком запроса Sec-Fetch-Storage-Access: inactive если пользователь уже предоставил разрешение. Для установки заголовка запроса никаких действий со стороны разработчика не требуется. Сервер может ответить заголовком Activate-Storage-Access: retry; allowed-origin="<origin>" , и браузер повторит запрос с необходимыми учётными данными.

Заголовок запроса

Sec-Fetch-Storage-Access: <access-status>

Когда пользователь посещает страницу со встроенным межсайтовым контентом, браузер автоматически включает заголовок Sec-Fetch-Storage-Access в межсайтовые запросы, которые могут требовать учётные данные (например, файлы cookie). Этот заголовок указывает на разрешение доступа к встроенному файлу cookie. Вот как интерпретировать его значения:

  • none : у встроенного элемента нет разрешения storage-access , и, следовательно, у него нет доступа к неразделенным файлам cookie.
  • inactive : у встроенного приложения есть разрешение storage-access , но оно не использует его. У встроенного приложения нет доступа к неразделённым файлам cookie.
  • active : встроенный файл cookie имеет неразделённый доступ. Это значение будет включено в любые запросы к другим источникам, имеющие доступ к неразделённым файлам cookie.

Заголовки ответа

Activate-Storage-Access: <retry-or-reload>

Заголовок Activate-Storage-Access указывает браузеру либо повторить запрос с cookie-файлами, либо загрузить ресурс напрямую с активированным SAA. Заголовок может принимать следующие значения:

  • load : дает указание браузеру предоставить разработчику доступ к неразделенным cookie-файлам для запрошенного ресурса.
  • retry : сервер отвечает, что браузер должен активировать разрешение на доступ к хранилищу, а затем повторить запрос.
Activate-Storage-Access: retry; allowed-origin="https://site.example"
Activate-Storage-Access: retry; allowed-origin=*
Activate-Storage-Access: load

Поддержка ресурсов, отличных от iframe

Обновление заголовков доступа к хранилищу позволяет использовать SAA для встроенного контента, не входящего в iframe, например, изображений, размещённых на другом домене. Ранее ни один API веб-платформ не позволял загружать такие ресурсы с учётными данными в браузерах при отсутствии сторонних файлов cookie. Например, ваш embedding-site.example может запросить изображение:

   <img src="https://server.example/image"/>

И сервер может ответить содержимым или ошибкой, в зависимости от того, доступен ли файл cookie:

app.get('/image', (req, res) => {
  const headers = req.headers;
  const cookieHeader = headers.cookie;
  // Check if the embed has the necessary cookie access
  if (!cookieHeader || !cookieHeader.includes('foo')) {
  // If the cookie is not present, check if the browser supports Storage Access headers
    if (
      'sec-fetch-storage-access' in headers &&
      headers['sec-fetch-storage-access'] == 'inactive'
    ) {
    // If the browser supports Storage Access API, retry the request with storage access enabled
      res.setHeader('Activate-Storage-Access', 'retry; allowed-origin="https://embedding-site.example"');
    }
    res.status(401).send('No cookie!');
   } else {
    // If the cookie is available, check if the user is authorized to access the image
    if (!check_authorization(cookieHeader)) {
      return res.status(401).send('Unauthorized!');
    }
    // If the user is authorized, respond with the image file
    res.sendFile("path/to/image.jpeg");
  }
});

Если файл cookie отсутствует, сервер проверяет значение заголовка запроса Sec-Fetch-Storage-Access . Если это значение равно inactive , сервер отвечает заголовком Activate-Storage-Access: retry , указывающим на необходимость повторной попытки запроса с доступом к хранилищу. Если файл cookie отсутствует и заголовок Sec-Fetch-Storage-Access не имеет значения inactive, изображение не загрузится.

Поток HTTP-заголовков

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

При использовании заголовков доступа к хранилищу последующие посещения страниц будут инициировать следующий поток:

  1. Пользователь снова посещает website.example , в который встроен calendar.example . Эта выборка, как и раньше, пока не имеет доступа к файлу cookie. Однако пользователь ранее предоставил разрешение storage-access , и выборка включает заголовок Sec-Fetch-Storage-Access: inactive , указывающий на то, что доступ к неразделённому файлу cookie возможен, но не используется.
  2. Сервер calendar.example отвечает заголовком Activate-Storage-Access: retry; allowed-origin="<origin>" (в этом случае <origin> будет https://website.example ), чтобы указать, что для извлечения ресурса требуется использование неразделенных файлов cookie с разрешением на доступ к хранилищу.
  3. Браузер повторяет запрос, на этот раз включая неразделенные файлы cookie (активируя разрешение storage-access для этой выборки).
  4. Сервер calendar.example отвечает персонализированным содержимым iframe. Ответ включает заголовок Activate-Storage-Access: load , указывающий, что браузер должен загрузить содержимое с активированным разрешением storage-access (то есть загрузить с неразделённым доступом к cookie, как если бы был вызван document.requestStorageAccess() ).
  5. Пользовательский агент загружает содержимое iframe с неразделённым доступом к cookie, используя разрешение на доступ к хранилищу. После этого виджет может работать как и ожидалось.
Блок-схема, иллюстрирующая поток заголовка доступа к хранилищу.
Диаграмма потока заголовка доступа к хранилищу.

Обновите свое решение

Используя функцию заголовков доступа к хранилищу, вам может потребоваться обновить свой код в двух случаях:

  1. Вы используете SAA и хотите добиться лучшей производительности с помощью логики заголовков.
  2. У вас есть проверка или логика, которая зависит от того, включен ли заголовок Origin в запрос на вашем сервере.

Реализовать логику заголовков SAA

Чтобы использовать заголовки доступа к хранилищу в вашем решении, вам необходимо обновить его. Предположим, вы являетесь владельцем calendar.example . Чтобы website.example мог загрузить персонализированный виджет calendar.example , код виджета должен иметь доступ к хранилищу.

Клиентская сторона

Функция заголовков доступа к хранилищу не требует обновления кода на стороне клиента для существующих решений. Ознакомьтесь с документацией, чтобы узнать, как реализовать SAA .

Серверная сторона

На стороне сервера вы можете использовать новые заголовки:

app.get('/cookie-access-endpoint', (req, res) => {
  const storageAccessHeader = req.headers['sec-fetch-storage-access'];

  if (storageAccessHeader === 'inactive') {
    // User needs to grant permission, trigger a prompt
    if (!validate_origin(req.headers.origin)) {
      res.status(401).send(`${req.headers.origin} is not allowed to send` +
          ' credentialed requests to this server.');
      return;
    }
    res.set('Activate-Storage-Access', `retry; allowed-origin="${req.headers.origin}"`);
    res.status(401).send('This resource requires storage access. Please grant permission.');
  } else if (storageAccessHeader === 'active') {
    // User has granted permission, proceed with access
    res.set('Activate-Storage-Access', 'load');
    // Include the actual iframe content here
    res.send('This is the content that requires cookie access.');
  } else {
    // Handle other cases (e.g., 'Sec-Fetch-Storage-Access': 'none')
  }
});

Посмотрите демо-версию , чтобы увидеть, как это решение работает на практике.

Обновите логику заголовка Origin

Благодаря заголовкам доступа к хранилищу Chrome отправляет заголовок Origin в большем количестве запросов, чем раньше. Это может повлиять на логику работы сервера, если он использует заголовок Origin только для определённых типов запросов (например, определённых CORS).

Чтобы избежать потенциальных проблем, вам необходимо проверить код на стороне сервера:

  • Проверьте наличие любой проверки или логики, зависящих от наличия заголовка Origin .
  • Обновите свой код, чтобы обрабатывать заголовок Origin , присутствующий в большем количестве случаев.

Основные преимущества

Заголовки доступа к хранилищу — рекомендуемый и более производительный способ использования SAA. В целом, это изменение вносит ряд улучшений:

  • Поддержка встраивания не-iframe: позволяет использовать SAA для более широкого спектра ресурсов.
  • Сокращение использования сети: меньше запросов и меньший объем полезной нагрузки.
  • Меньше использования ЦП: меньше обработки JavaScript.
  • Улучшенный UX: устранение мешающих промежуточных загрузок.

Примите участие в исследовании происхождения

Пробные версии Origin позволяют вам опробовать новые функции и оставить отзыв об их удобстве использования, практичности и эффективности. Подробнее см. в статье «Начало работы с пробными версиями Origin» .

Вы можете попробовать функцию заголовков доступа к хранилищу, зарегистрировавшись в пробных версиях Origin, начиная с Chrome 130. Чтобы принять участие в пробной версии Origin:

  1. Перейдите на страницу регистрации пробной версии Storage Access Headers.
  2. Следуйте инструкциям по участию в исследовании происхождения.

Тестирование локально

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

Чтобы настроить экземпляр Chrome, выполните следующие действия:

  1. Включите флаг Chrome на chrome://flags/#storage-access-headers .
  2. Перезапустите Chrome, чтобы изменения вступили в силу.

Привлекайте и делитесь отзывами

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