Related Website Sets (RWS) — это механизм веб-платформы, помогающий браузерам понимать взаимосвязи между набором доменов. Это позволяет браузерам принимать ключевые решения для включения определенных функций сайта (например, разрешать ли доступ к межсайтовым файлам cookie) и представлять эту информацию пользователям.
Многие сайты используют несколько доменов для обеспечения единого пользовательского интерфейса. Организациям может потребоваться поддерживать разные домены верхнего уровня для различных сценариев использования, например, домены для конкретных стран или домены сервисов для размещения изображений или видео. Функция «Наборы связанных веб-сайтов» позволяет сайтам обмениваться данными между доменами с определенными настройками.
Что такое набор связанных веб-сайтов?
В общих чертах, набор связанных веб-сайтов представляет собой совокупность доменов, для которых существует один «основной домен» и потенциально несколько «дополнительных доменов».
В следующем примере параметр primary отображает основной домен, а associatedSites — домены, соответствующие требованиям связанного подмножества .
{
"primary": "https://primary.com",
"associatedSites": ["https://associate1.com", "https://associate2.com", "https://associate3.com"]
}
Список связанных наборов веб-сайтов находится в общедоступном JSON-файле , размещенном на GitHub . Это канонический источник всех утвержденных наборов. Браузеры используют этот файл для определения того, принадлежат ли сайты к одному и тому же связанному набору веб-сайтов.
Только лица, обладающие административным контролем над доменом, могут создавать наборы с этим доменом. Авторы должны указать связь между каждым «членом набора» и его «основным элементом набора». Члены набора могут включать различные типы доменов и должны быть частью подмножества, основанного на сценарии использования .
Если ваше приложение зависит от доступа к межсайтовым файлам cookie (также называемым файлами cookie третьих сторон) на разных сайтах в рамках одного и того же набора связанных веб-сайтов, вы можете использовать API доступа к хранилищу (SAA) и API requestStorageAccessFor для запроса доступа к этим файлам cookie. В зависимости от подмножества, к которому относится каждый сайт, браузер может обрабатывать запрос по-разному.
Чтобы узнать больше о процессе и требованиях к подаче наборов, ознакомьтесь с рекомендациями по подаче заявок . Представленные наборы пройдут различные технические проверки для подтверждения их качества.
Примеры использования связанных веб-сайтов
Наборы связанных веб-сайтов хорошо подходят для случаев, когда организации необходима форма единой идентичности для разных сайтов верхнего уровня.
Вот некоторые примеры использования наборов связанных веб-сайтов:
- Настройка под конкретные страны . Использование локализованных сайтов при одновременном применении общей инфраструктуры (например, example.co.uk может использовать сервис, размещенный на example.ca).
- Интеграция сервисных доменов . Использование сервисных доменов, с которыми пользователи никогда напрямую не взаимодействуют, но которые предоставляют услуги на сайтах одной и той же организации (например, cdn.com).
- Разделение пользовательского контента . Доступ к данным на разных доменах, который отделяет загруженный пользователями контент от остального контента сайта по соображениям безопасности, одновременно предоставляя изолированному домену доступ к аутентификационным (и другим) файлам cookie. Если вы предоставляете доступ к неактивному контенту, загруженному пользователями, вы также можете безопасно разместить его на том же домене, следуя рекомендациям .
- Встроенный аутентифицированный контент . Поддержка встроенного контента с различных аффилированных ресурсов (видео, документы или ресурсы, доступ к которым ограничен для пользователя, вошедшего в систему на главном сайте).
- Вход в систему . Поддержка входа в систему на всех аффилированных ресурсах. API FedCM также может быть подходящим для некоторых сценариев использования.
- Аналитика . Внедрение аналитических инструментов и методов измерения пользовательских маршрутов на аффилированных ресурсах для повышения качества предоставляемых услуг.
Подробности интеграции связанных наборов веб-сайтов
API доступа к хранилищу
API доступа к хранилищу (SAA) предоставляет встроенному контенту из других источников возможность доступа к хранилищу, к которому он обычно имеет доступ только в контексте собственного источника.
Встроенные ресурсы могут использовать методы SAA для проверки наличия у них в данный момент доступа к хранилищу и для запроса доступа у пользовательского агента.
Если сторонние файлы cookie заблокированы, но включена функция «Наборы связанных веб-сайтов» (Related Website Sets, RWS), Chrome автоматически предоставит разрешение в контекстах внутри RWS, в противном случае отобразит пользователю запрос. («Контекст внутри RWS» — это контекст, например, iframe, встроенный сайт и сайт верхнего уровня которого находятся в одном и том же RWS.)
Проверьте и запросите доступ к хранилищу.
Чтобы проверить, имеют ли они в данный момент доступ к хранилищу, встроенные сайты могут использовать метод Document.hasStorageAccess() .
Метод возвращает промис, который разрешается логическим значением, указывающим, имеет ли документ уже доступ к своим куки или нет. Промис также возвращает true, если iframe имеет тот же источник, что и верхний фрейм.
Для запроса доступа к файлам cookie в контексте межсайтовых операций встроенные сайты могут использовать Document.requestStorageAccess() (rSA).
API-функция requestStorageAccess() предназначена для вызова из iframe. Этот iframe должен только что получить взаимодействие с пользователем ( жест пользователя , который требуется всеми браузерами), но Chrome дополнительно требует, чтобы в какой-то момент за последние 30 дней пользователь посетил сайт, которому принадлежит этот iframe, и взаимодействовал именно с этим сайтом — как с документом верхнего уровня, а не внутри iframe.
requestStorageAccess() возвращает промис, который срабатывает, если доступ к хранилищу был предоставлен. Если доступ был запрещен по какой-либо причине, промис отклоняется с указанием причины.
requestStorageAccessFor в Chrome
API доступа к хранилищу позволяет встраиваемым сайтам запрашивать доступ к хранилищу только из элементов <iframe> , с которыми взаимодействовал пользователь.
Это создает проблемы при внедрении API доступа к хранилищу для сайтов верхнего уровня, использующих межсайтовые изображения или теги скриптов, требующие использования файлов cookie.
Для решения этой проблемы Chrome реализовал способ, позволяющий сайтам верхнего уровня запрашивать доступ к хранилищу от имени конкретных источников с помощью Document.requestStorageAccessFor() (rSAFor).
document.requestStorageAccessFor('https://target.site')
API-функция requestStorageAccessFor() предназначена для вызова из документа верхнего уровня. Этот документ также должен быть недавно обработан пользователем. Но в отличие от requestStorageAccess() , Chrome не проверяет наличие взаимодействия с документом верхнего уровня за последние 30 дней, поскольку пользователь уже находится на странице.
Проверьте права доступа к хранилищу.
Доступ к некоторым функциям браузера, таким как камера или геолокация, зависит от предоставленных пользователем разрешений. API разрешений позволяет проверить статус разрешения на доступ к API — предоставлено ли оно, отклонено ли оно или требует какого-либо взаимодействия с пользователем, например, нажатия на запрос или взаимодействия со страницей.
Вы можете запросить статус разрешений, используя navigator.permissions.query() .
Для проверки прав доступа к хранилищу для текущего контекста необходимо передать строку 'storage-access' :
navigator.permissions.query({name: 'storage-access'})
Для проверки прав доступа к хранилищу для указанного источника необходимо передать строку 'top-level-storage-access' :
navigator.permissions.query({name: 'top-level-storage-access', requestedOrigin: 'https://target.site'})
Обратите внимание, что для защиты целостности встроенного источника проверяются только разрешения, предоставленные документом верхнего уровня с помощью document.requestStorageAccessFor .
В зависимости от того, может ли разрешение быть предоставлено автоматически или требует действий пользователя, будет возвращено prompt или granted .
покадровая модель
Гранты rSA применяются к каждому кадру . Гранты rSA и rSAFor рассматриваются как отдельные разрешения.
Каждый новый фрейм должен будет запрашивать доступ к хранилищу индивидуально, и доступ будет предоставлен автоматически. Только первый запрос требует жеста пользователя; любые последующие запросы, инициированные iframe, такие как навигация или доступ к подресурсам, не будут ждать жеста пользователя, поскольку он будет предоставлен для сеанса просмотра первоначальным запросом.
Для обновления, перезагрузки или иного повторного создания iframe потребуется повторно запросить доступ.
требования к файлам cookie
Файлы cookie должны содержать атрибуты SameSite=None и Secure , поскольку rSA предоставляет доступ только к тем файлам cookie, которые уже помечены для использования в межсайтовых контекстах .
Файлы cookie с атрибутами SameSite=Lax , SameSite=Strict или без атрибута SameSite предназначены только для использования на уровне первого сайта и никогда не будут передаваться в межсайтовом контексте, независимо от rSA.
Безопасность
Для rSAFor запросы к подресурсам требуют наличия заголовков Cross-Origin Resource Sharing (CORS) или атрибута crossorigin в ресурсах, что гарантирует явное согласие на их использование.
Примеры реализации
Запросить доступ к хранилищу из встроенного iframe, работающего в другом источнике.

requestStorageAccess() во встроенном контенте на другом сайте. Проверьте, есть ли у вас доступ к хранилищу.
Чтобы проверить, есть ли у вас уже доступ к хранилищу, используйте document.hasStorageAccess() .
Если обещание выполняется, вы можете получить доступ к хранилищу в контексте межсайтового взаимодействия. Если оно выполняется, вам необходимо запросить доступ к хранилищу.
document.hasStorageAccess().then((hasAccess) => {
if (hasAccess) {
// You can access storage in this context
} else {
// You have to request storage access
}
});
Запросить доступ к хранилищу
Если вам необходимо запросить доступ к хранилищу, сначала проверьте разрешение на доступ к хранилищу navigator.permissions.query({name: 'storage-access'}) чтобы узнать, требуется ли для этого действие пользователя или оно может быть предоставлено автоматически.
Если разрешение granted , вы можете вызвать document.requestStorageAccess() , и операция должна пройти успешно без каких-либо действий со стороны пользователя.
Если статус запроса разрешений — prompt , то вызов document.requestStorageAccess() необходимо инициировать после действия пользователя, например, нажатия кнопки.
Пример:
navigator.permissions.query({name: 'storage-access'}).then(res => {
if (res.state === 'granted') {
// Permission has already been granted
// You can request storage access without any user gesture
rSA();
} else if (res.state === 'prompt') {
// Requesting storage access requires user gesture
// For example, clicking a button
const btn = document.createElement("button");
btn.textContent = "Grant access";
btn.addEventListener('click', () => {
// Request storage access
rSA();
});
document.body.appendChild(btn);
}
});
function rSA() {
if ('requestStorageAccess' in document) {
document.requestStorageAccess().then(
(res) => {
// Use storage access
},
(err) => {
// Handle errors
}
);
}
}
Последующие запросы из фрейма, навигации или подресурсов автоматически получат разрешение на доступ к межсайтовым куки. hasStorageAccess() возвращает true, и межсайтовые куки с того же набора связанных веб-сайтов будут отправлены в этих запросах без каких-либо дополнительных вызовов JavaScript.
Сайты верхнего уровня запрашивают доступ к файлам cookie от имени сайтов, расположенных в других регионах.

requestStorageAccessFor() на сайте верхнего уровня для другого источника. Сайты верхнего уровня могут использовать requestStorageAccessFor() для запроса доступа к хранилищу от имени конкретных источников.
hasStorageAccess() проверяет только наличие доступа к хранилищу у сайта, вызывающего её, поэтому сайт верхнего уровня может проверить разрешения для другого источника.
Чтобы узнать, будет ли пользователю предложено предоставить доступ к хранилищу или доступ к хранилищу уже предоставлен указанному источнику, вызовите navigator.permissions.query({name: 'top-level-storage-access', requestedOrigin: 'https://target.site'}) .
Если разрешение granted , вы можете вызвать document.requestStorageAccessFor('https://target.site') . Операция должна пройти успешно без каких-либо действий со стороны пользователя.
Если запрос на предоставление доступа выполняется prompt , вам потребуется привязать вызов document.requestStorageAccessFor('https://target.site') к действиям пользователя, например, к нажатию кнопки.
Пример:
navigator.permissions.query({name:'top-level-storage-access',requestedOrigin: 'https://target.site'}).then(res => {
if (res.state === 'granted') {
// Permission has already been granted
// You can request storage access without any user gesture
rSAFor();
} else if (res.state === 'prompt') {
// Requesting storage access requires user gesture
// For example, clicking a button
const btn = document.createElement("button");
btn.textContent = "Grant access";
btn.addEventListener('click', () => {
// Request storage access
rSAFor();
});
document.body.appendChild(btn);
}
});
function rSAFor() {
if ('requestStorageAccessFor' in document) {
document.requestStorageAccessFor().then(
(res) => {
// Use storage access
},
(err) => {
// Handle errors
}
);
}
}
После успешного вызова requestStorageAccessFor() межсайтовые запросы будут включать файлы cookie, если они содержат CORS или атрибут crossorigin, поэтому сайтам, возможно, стоит подождать, прежде чем отправлять запрос.
Запросы должны использовать credentials: 'include' , а ресурсы должны содержать атрибут crossorigin="use-credentials" .
function checkCookie() {
fetch('https://related-website-sets.glitch.me/getcookies.json', {
method: 'GET',
credentials: 'include'
})
.then((response) => response.json())
.then((json) => {
// Do something
});
}
Как провести локальное тестирование
Предварительные требования
Для локального тестирования наборов связанных веб-сайтов используйте Chrome версии 119 или выше, запущенный из командной строки, и включите флаг Chrome test-third-party-cookie-phaseout .
Включить флаг Chrome
Чтобы включить необходимый флаг Chrome, перейдите по chrome://flags#test-third-party-cookie-phaseout в адресной строке и измените значение флага на Enabled . После изменения флагов обязательно перезапустите браузер.
Запустите Chrome с локальной настройкой связанных веб-сайтов.
Чтобы запустить Chrome с локально объявленным набором связанных веб-сайтов, создайте JSON-объект, содержащий URL-адреса, входящие в этот набор, и передайте его параметру --use-related-website-set .
Узнайте больше о том, как запускать Chromium с использованием флагов .
--use-related-website-set="{\"primary\": \"https://related-website-sets.glitch.me\", \"associatedSites\": [\"https://rws-member-1.glitch.me\"]}" \
https://related-website-sets.glitch.me/
Пример
Чтобы включить отображение наборов связанных веб-сайтов локально, необходимо активировать параметр test-third-party-cookie-phaseout в chrome://flags и запустить Chrome из командной строки с флагом --use-related-website-set указав в качестве JSON-объекта URL-адреса, входящие в набор.
--use-related-website-set="{\"primary\": \"https://related-website-sets.glitch.me\", \"associatedSites\": [\"https://rws-member-1.glitch.me\"]}" \
https://related-website-sets.glitch.me/
Убедитесь, что у вас есть доступ к межсайтовым файлам cookie.
Вызовите API (rSA или rSAFor) с тестируемых сайтов и проверьте доступ к межсайтовым файлам cookie.
Процесс подачи заявок на создание связанных наборов веб-сайтов
Выполните следующие шаги, чтобы объявить взаимосвязь между доменами и указать, к какому подмножеству они относятся.
1. Определите свой RWS.
Определите соответствующие домены, включая основной набор и элементы набора , которые войдут в состав набора связанных веб-сайтов. Также укажите, к какому типу подмножества относится каждый элемент набора.
2. Создайте заявку RWS.
Создайте локальную копию (клон или форк) репозитория GitHub . В новой ветке внесите изменения в файл related_website_sets.JSON , чтобы отразить ваш набор. Чтобы убедиться, что ваш набор имеет правильный формат и структуру JSON, вы можете использовать инструмент генерации JSON .
3. Убедитесь, что ваша система RWS соответствует техническим требованиям.
Убедитесь, что требования к формированию набора данных и требования к проверке набора данных выполнены.
4. Протестируйте вашу систему RWS локально.
Прежде чем создавать запрос на слияние (Pull Request) для отправки вашего набора данных, протестируйте его локально, чтобы убедиться, что он проходит все необходимые проверки.
5. Отправьте свой RWS.
Для добавления списка связанных веб-сайтов создайте запрос на слияние (PR) в файл related_website_sets.JSON , где Chrome размещает канонический список связанных веб-сайтов. (Для создания запросов на слияние требуется учетная запись GitHub, и вам необходимо будет подписать лицензионное соглашение участника (CLA), прежде чем вы сможете внести свой вклад в список.)
После создания запроса на изменение выполняется ряд проверок, чтобы убедиться в соблюдении требований шага 3, таких как подписание соглашения о конфиденциальности (CLA) и действительность файла .well-known .
В случае успешного прохождения проверок в запросе на слияние (PR) будет указано, что они пройдены. Одобренные запросы на слияние будут вручную объединяться партиями в канонический список связанных веб-сайтов один раз в неделю (по вторникам в 12:00 по восточному времени). Если какая-либо из проверок не пройдена, отправитель получит уведомление об ошибке запроса на слияние на GitHub. Отправитель может исправить ошибки и обновить запрос на слияние, при этом следует помнить, что:
- Если запрос на слияние не удастся, появится сообщение об ошибке с дополнительной информацией о причинах сбоя отправки ( пример ).
- Все технические проверки, касающиеся отправки наборов данных, проводятся на GitHub, и, следовательно, все ошибки при отправке, возникшие в результате технических проверок, будут доступны для просмотра на GitHub.
Корпоративные политики
В Chrome действуют две политики, призванные удовлетворить потребности корпоративных пользователей:
- Системы, которые могут не интегрироваться с функцией «Наборы связанных веб-сайтов», могут отключить эту функцию во всех корпоративных экземплярах Chrome с помощью политики
RelatedWebsiteSetsEnabled.- В некоторых корпоративных системах есть сайты только для внутреннего использования (например, интранет) с регистрируемыми доменами, которые отличаются от доменов в их наборе связанных веб-сайтов. Если им необходимо рассматривать эти сайты как часть набора связанных веб-сайтов, не раскрывая их публично (поскольку домены могут быть конфиденциальными), они могут дополнить или переопределить свой общедоступный список наборов связанных веб-сайтов с помощью политики
RelatedWebsiteSetsOverrides.
- В некоторых корпоративных системах есть сайты только для внутреннего использования (например, интранет) с регистрируемыми доменами, которые отличаются от доменов в их наборе связанных веб-сайтов. Если им необходимо рассматривать эти сайты как часть набора связанных веб-сайтов, не раскрывая их публично (поскольку домены могут быть конфиденциальными), они могут дополнить или переопределить свой общедоступный список наборов связанных веб-сайтов с помощью политики
Chrome разрешает любое пересечение общедоступных и корпоративных наборов данных одним из двух способов, в зависимости от того, указаны ли replacements или additions .
Например, для общедоступного набора {primary: A, associated: [B, C]} :
Комплект replacements : | {primary: C, associated: [D, E]} |
| Комплекс предприятий поглощает общий объект, образуя новый комплекс. | |
| Полученные наборы: | {primary: A, associated: [B]}{primary: C, associated: [D, E]} |
набор additions : | {primary: C, associated: [D, E]} |
| Наборы данных для публичных и корпоративных пользователей объединены. | |
| Полученный набор: | {primary: C, associated: [A, B, D, E]} |
Устранение неполадок, связанных с наборами веб-сайтов.
«Подсказка пользователя» и «жест пользователя»
«Запрос пользователя» и «жест пользователя» — это разные вещи. Chrome не будет показывать пользователям запрос на разрешение для сайтов, входящих в тот же набор связанных веб-сайтов, но Chrome всё равно требует, чтобы пользователь взаимодействовал со страницей. Прежде чем предоставить разрешение, Chrome требует жеста пользователя , также называемого «взаимодействием пользователя» или «активацией пользователя». Это связано с тем, что использование API доступа к хранилищу вне контекста набора связанных веб-сайтов (а именно requestStorageAccess() ) также требует жеста пользователя в соответствии с принципами проектирования веб-платформы .
Доступ к файлам cookie или хранилищам других сайтов.
Наборы связанных веб-сайтов не объединяют хранилище для разных сайтов: они просто упрощают (без запроса подтверждения) вызовы requestStorageAccess() . Наборы связанных веб-сайтов лишь снижают неудобства для пользователя при использовании API доступа к хранилищу, но не диктуют, что делать после восстановления доступа. Если A и B — разные сайты в одном наборе связанных веб-сайтов, и A включает B, B может вызвать requestStorageAccess() и получить доступ к хранилищу первого сайта без запроса подтверждения у пользователя. Наборы связанных веб-сайтов не осуществляют межсайтовую коммуникацию. Например, создание набора связанных веб-сайтов не приведет к тому, что файлы cookie, принадлежащие B, начнут отправляться в A. Если вы хотите поделиться этими данными, вам придется сделать это самостоятельно, например, отправив window.postMessage из iframe B во фрейм A.
Доступ к файлам cookie без разделения по умолчанию
Наборы связанных веб-сайтов не допускают неявного доступа к неразделённым файлам cookie без вызова какого-либо API. Межсайтовые файлы cookie по умолчанию недоступны в рамках набора; наборы связанных веб-сайтов просто позволяют сайтам внутри набора пропускать запрос разрешения на доступ к API хранилища . iframe должен вызвать document.requestStorageAccess() , чтобы получить доступ к своим файлам cookie, или страница верхнего уровня может вызвать document.requestStorageAccessFor() .
Поделитесь своим мнением
Отправка набора данных на GitHub и работа с API доступа к хранилищу и API requestStorageAccessFor — это возможности поделиться своим опытом работы с этим процессом и любыми проблемами, с которыми вы столкнетесь.
Чтобы присоединиться к обсуждениям по теме «Наборы похожих веб-сайтов»:
- Присоединитесь к общедоступной рассылке Related Website Sets.
- Задавайте вопросы и следите за обсуждением в репозитории GitHub "Похожие наборы веб-сайтов" .