Same-Origin Policy и зачем нужен CORS
Браузер реализует Same-Origin Policy (SOP): JavaScript-код, загруженный с домена shop.ru, не может по умолчанию читать ответы от api.personalization.com. Это защита от атак, при которых вредоносный сайт мог бы читать данные с других сайтов от имени авторизованного пользователя.
CORS — механизм, позволяющий серверу явно разрешить запросы с определённых доменов, исключив их из действия SOP.
Как работает CORS
Простой запрос (GET без кастомных заголовков):
1. Браузер отправляет запрос с заголовком Origin: https://shop.ru.
2. Сервер проверяет: разрешён ли этот origin?
3. Если да — возвращает Access-Control-Allow-Origin: https://shop.ru.
4. Браузер пропускает ответ в JS.
Preflight для сложных запросов:
OPTIONS /api/recommendations HTTP/1.1
Origin: https://shop.ru
Access-Control-Request-Method: POST
Access-Control-Request-Headers: Content-Type, X-API-Key
Сервер должен ответить:
Access-Control-Allow-Origin: https://shop.ru
Access-Control-Allow-Methods: POST, GET, OPTIONS
Access-Control-Allow-Headers: Content-Type, X-API-Key
Access-Control-Max-Age: 86400
CORS при интеграции платформы персонализации
При подключении JavaScript-виджета рекомендаций браузер делает запрос к API персонализации с другого домена. Если сервер не вернул нужные CORS-заголовки:
- Браузер блокирует ответ (не запрос — сервер его получает)
- В консоли появляется ошибка
CORS policy: No 'Access-Control-Allow-Origin' header - Рекомендации не отображаются, хотя на сервере всё работает
Важно: CORS-ошибка видна только в браузере. Если тестировать API через curl или Postman — всё работает, потому что эти инструменты не реализуют SOP. Проверяйте интеграцию в реальном браузере с включёнными DevTools.
Распространённые ошибки настройки
| Ошибка | Симптом | Решение |
|---|---|---|
| Нет CORS-заголовка | Рекомендации не грузятся | Добавить Access-Control-Allow-Origin |
| Wildcard (*) + credentials | Запрос с cookie блокируется | Указать конкретный origin + Allow-Credentials: true |
| Нет обработки OPTIONS | Preflight возвращает 404 | Добавить обработчик OPTIONS в роутер |
| Неправильный домен | CORS ошибка на поддомене | Разрешить *.shop.ru или каждый поддомен отдельно |