CORS (Cross-Origin Resource Sharing)
Что такое CORS и зачем он нужен?
Чтобы понять, что такое CORS, нужно разобраться, как браузер работает с запросами между сайтами. По умолчанию действует политика одного источника – Same-Origin Policy (SOP). Она ограничивает возможность JavaScript-кода одной страницы получать данные с другого источника без специального разрешения.
Источником считается комбинация протокола, домена и порта. Например, https://example.com и https://api.example.com считаются разными источниками, хотя относятся к одному основному домену. Аналогично отличаются адреса с HTTP и HTTPS или разными портами.
По сути, CORS – это механизм, с помощью которого сервер сообщает браузеру, разрешено ли странице с другого источника читать ответ на запрос. Если соответствующее разрешение отсутствует, браузер не предоставляет JavaScript доступ к полученным данным.
Такой подход необходим в современных веб-приложениях, где интерфейс и серверная логика часто работают отдельно. Например, frontend интернет-магазина может размещаться на одном домене, а API с информацией о товарах, заказах и пользователях – на другом.
При реализации API-интеграций правильная настройка междоменного доступа помогает организовать обмен данными между клиентской частью приложения и внешними сервисами без нарушения браузерных ограничений.
Как работает CORS на техническом уровне?
Механизм основан на специальных HTTP-заголовках, которые передаются между браузером и сервером. Когда JavaScript отправляет запрос к другому источнику, браузер указывает его происхождение в заголовке Origin.
Сервер анализирует запрос и возвращает ответ с настройками доступа. Например, заголовок Access-Control-Allow-Origin сообщает, какому источнику разрешено читать данные. Упрощенно процесс выглядит так:
- пользователь открывает веб-приложение;
- frontend отправляет запрос к API на другом источнике;
- браузер добавляет заголовок Origin;
- сервер обрабатывает запрос и возвращает CORS-заголовки;
- браузер проверяет полученные разрешения;
- если условия соблюдены, JavaScript получает доступ к ответу.
Например, интерфейс на https://shop.example.com обращается к API на https://api.example.com. Если сервер разрешает запросы с https://shop.example.com, браузер позволяет приложению прочитать полученные данные.
Однако если нужные заголовки отсутствуют, браузер блокирует доступ JavaScript к ответу. При этом сам HTTP-запрос в некоторых случаях уже мог быть отправлен и обработан сервером.
Этот механизм особенно актуален для приложений на React.js, Vue и Angular, где пользовательский интерфейс активно взаимодействует с backend через API.
Для чего нужен CORS в веб-разработке?
Основная задача механизма – обеспечить контролируемый обмен ресурсами между разными источниками, сохраняя ограничения браузерной безопасности. Он применяется в ситуациях, когда:
- frontend и backend расположены на разных доменах;
- сайт использует API стороннего сервиса;
- веб-приложение обращается к отдельному серверу авторизации;
- административная панель работает на поддомене;
- приложение получает данные из облачной инфраструктуры;
- несколько веб-сервисов используют общий API.
Например, интернет-магазин может получать данные о товарах из отдельного backend-сервиса, а личный кабинет – обращаться к API для просмотра заказов. Если интерфейс и сервер находятся на разных источниках, CORS определяет, разрешено ли браузеру передавать полученный ответ JavaScript-коду страницы.
Важно понимать, что такие ограничения действуют именно в браузере. При прямом обращении к API из серверного приложения, например через backend на Node.js, браузерная проверка междоменного доступа обычно не применяется.
Поэтому CORS нужен прежде всего для безопасного взаимодействия клиентской части приложения с ресурсами других источников, а не для ограничения всех обращений к серверу.
Какие HTTP-заголовки используются в CORS?
Работа механизма зависит от нескольких HTTP-заголовков. Они позволяют серверу указывать разрешенные источники, методы запросов, дополнительные заголовки и условия передачи учетных данных.
- Access-Control-Allow-Origin определяет, каким источникам разрешено читать ответ. Например, сервер может указать конкретный домен или использовать символ * для общедоступных ресурсов, не требующих передачи учетных данных.
- Access-Control-Allow-Methods перечисляет допустимые HTTP-методы, например GET, POST, PUT или DELETE. Этот заголовок используется при предварительной проверке запроса.
- Access-Control-Allow-Headers определяет, какие дополнительные заголовки клиент может передавать. Это важно, когда запрос содержит Authorization, нестандартные заголовки или определенные типы Content-Type.
- Access-Control-Allow-Credentials сообщает браузеру, разрешено ли предоставлять JavaScript доступ к ответу на междоменный запрос с учетными данными, например cookie.
- Access-Control-Max-Age определяет, сколько времени браузер может кешировать результат предварительной проверки.
Например, сервер может вернуть:
Access-Control-Allow-Origin: https://shop.example.com
Это означает, что JavaScript страницы с указанного источника сможет прочитать ответ при выполнении остальных условий CORS.
Для запросов с учетными данными нельзя использовать Access-Control-Allow-Origin: *. В таком случае необходимо указать конкретный разрешенный источник.
Что такое Preflight Request?
Не все междоменные запросы выполняются одинаково. Для определенных HTTP-методов и заголовков браузер сначала отправляет предварительный запрос – preflight.
Он использует метод OPTIONS и позволяет проверить, разрешает ли сервер будущий запрос.
Например, если веб-приложение отправляет POST-запрос с Content-Type: application/json, браузер обычно сначала проверяет, принимает ли сервер такой метод и заголовок от данного источника. Процесс состоит из нескольких этапов:
- Браузер отправляет OPTIONS-запрос.
- Сервер возвращает разрешенные методы, заголовки и источники.
- Браузер проверяет ответ.
- Если условия выполнены, отправляется основной запрос.
- Ответ основного запроса также проходит проверку CORS.
Preflight помогает браузеру проверить разрешения до отправки определенных междоменных запросов. Однако он не заменяет проверку авторизации и прав доступа на сервере.
Как выполняется настройка CORS?
Настройка CORS обычно выполняется на backend, API-сервере, reverse proxy или API Gateway. Конкретный способ зависит от используемых технологий и архитектуры проекта.
Основная задача разработчика – определить, каким источникам разрешено получать ответы сервера и какие запросы должны поддерживаться. Процесс включает:
- определение разрешенных доменов и поддоменов;
- настройку Access-Control-Allow-Origin;
- указание необходимых HTTP-методов;
- разрешение требуемых заголовков;
- настройку работы с cookie и авторизацией;
- обработку предварительных OPTIONS-запросов;
- проверку поведения приложения в разных окружениях.
Например, для API интернет-магазина можно разрешить обращения из браузерного интерфейса https://shop.example.com, но не открывать доступ всем сторонним сайтам.
В проектах с несколькими окружениями разрешенные источники могут различаться. Локальная разработка использует localhost, тестовая версия – staging-домен, а рабочая – production-адрес.
При этом сервер должен применять настройки отдельно для каждой среды, чтобы временные разрешения для разработки случайно не остались в публичном приложении.
Важно учитывать и работу кеширования: если сервер динамически возвращает разрешенный Origin из списка доверенных источников, для корректной обработки кешем обычно необходим заголовок Vary: Origin.
Почему возникает CORS Error?
CORS Error – распространенная ошибка при разработке сайтов и приложений, которые обращаются к API на другом источнике.
Она означает, что браузер не смог предоставить JavaScript доступ к ответу из-за нарушения правил междоменного обмена. Однако, причина не всегда заключается непосредственно в отсутствии одного заголовка. Чаще всего ошибка возникает, если:
- сервер не возвращает Access-Control-Allow-Origin;
- запрашивающий источник отсутствует в списке разрешенных;
- сервер не обрабатывает OPTIONS-запрос;
- не разрешен нужный HTTP-метод;
- отсутствует разрешение на дополнительный заголовок;
- используется wildcard вместе с передачей учетных данных;
- запрос перенаправляется или завершается сетевой ошибкой;
- конфигурации staging и production различаются.
Например, frontend может успешно работать локально, но после деплоя перестать получать данные из API. Причина может заключаться в том, что production-домен не был добавлен в список разрешенных источников.
Для диагностики разработчики используют DevTools браузера. Во вкладке Network можно проверить Origin, параметры preflight-запроса и заголовки ответа, а во вкладке Console – увидеть сообщение об ошибке.
Такие сценарии желательно проверять в рамках QA/QC тестирования сайта, особенно если проект использует авторизацию, формы, платежи и сторонние API.
Чем CORS отличается от авторизации и других механизмов безопасности?
CORS часто воспринимают как полноценную защиту API, но это не совсем правильно. Он контролирует возможность браузерного JavaScript читать ответы с другого источника, однако не запрещает прямые запросы к серверу из других программ. Поэтому механизм не заменяет:
- авторизацию и проверку прав пользователя;
- защиту от CSRF;
- фильтрацию и валидацию входящих данных;
- HTTPS и шифрование соединения;
- ограничение частоты запросов;
- контроль доступа к ресурсам API.
Например, злоумышленник может отправить запрос непосредственно на сервер, не используя браузер. В таком случае CORS сам по себе не предотвратит обращение. Именно поэтому backend должен самостоятельно проверять токены, сессии, роли и права доступа.
Неправильная конфигурация тоже может создавать риски. Если сервер автоматически разрешает любой Origin и одновременно допускает запросы с учетными данными, это может привести к раскрытию конфиденциальных ответов сторонним веб-страницам.
Поэтому правила междоменного обмена нужно рассматривать как один из компонентов общей системы безопасности.
В чем значение CORS для бизнеса и разработки?
Для бизнеса CORS важен прежде всего стабильной работой цифровых продуктов. Если междоменные запросы настроены неправильно, пользователи могут столкнуться с неработающими формами, отсутствием данных в личном кабинете, ошибками загрузки каталога или сбоями отдельных функций.
Для разработчиков это необходимая часть взаимодействия frontend и backend. Корректная конфигурация помогает организовать обмен данными между приложениями, API и облачными сервисами, не отключая ограничения браузера ради удобства разработки.
Особенно важен этот механизм при создании сложных продуктов: SaaS-платформ, маркетплейсов, интернет-магазинов и корпоративных веб-систем. В таких проектах веб-разработка часто предполагает несколько отдельных сервисов, которым необходимо безопасно взаимодействовать друг с другом.
В итоге, CORS – это механизм управления междоменным доступом в браузере. Он помогает веб-приложениям работать с ресурсами других источников, сохраняя контроль над тем, какие страницы могут читать ответы сервера. Правильная настройка обеспечивает предсказуемую работу API, снижает риск ошибок интеграции и поддерживает безопасность цифрового продукта.