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-заголовков. Они позволяют серверу указывать разрешенные источники, методы запросов, дополнительные заголовки и условия передачи учетных данных.

  1. Access-Control-Allow-Origin определяет, каким источникам разрешено читать ответ. Например, сервер может указать конкретный домен или использовать символ * для общедоступных ресурсов, не требующих передачи учетных данных.
  2. Access-Control-Allow-Methods перечисляет допустимые HTTP-методы, например GET, POST, PUT или DELETE. Этот заголовок используется при предварительной проверке запроса.
  3. Access-Control-Allow-Headers определяет, какие дополнительные заголовки клиент может передавать. Это важно, когда запрос содержит Authorization, нестандартные заголовки или определенные типы Content-Type.
  4. Access-Control-Allow-Credentials сообщает браузеру, разрешено ли предоставлять JavaScript доступ к ответу на междоменный запрос с учетными данными, например cookie.
  5. 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, браузер обычно сначала проверяет, принимает ли сервер такой метод и заголовок от данного источника. Процесс состоит из нескольких этапов:

  1. Браузер отправляет OPTIONS-запрос.
  2. Сервер возвращает разрешенные методы, заголовки и источники.
  3. Браузер проверяет ответ.
  4. Если условия выполнены, отправляется основной запрос.
  5. Ответ основного запроса также проходит проверку 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, снижает риск ошибок интеграции и поддерживает безопасность цифрового продукта.