Gernar
Frontend DeveloperHTTP, API и сеть

Интервью-вопрос

Что такое CORS

CORS это механизм браузера для cross-origin запросов. Он важен для фронтенда, потому что ошибка в настройке API ломает чтение ответа, авторизацию через cookies и запросы с preflight.

Добавлен
Редакция

Подготовьте короткий ответ и пару деталей на случай уточняющих вопросов.

🐰0
🥚0

Мини-квиз

Проверка перед разбором

Несколько быстрых вопросов перед разбором. Так проще поймать места, которые только кажутся понятными.

Вопрос 1 из 50 правильно

Как лучше объяснить CORS на интервью?

Вы хотите дать короткое определение без лишней лекции.

Варианты ответа

Разбор

Разобраться, а не зазубрить

Дальше разбираем суть, типичные уточнения и места, где легко сказать лишнее или перепутать термины.

Базовая идея

CORS нужен из-за Same-Origin Policy. По умолчанию браузер ограничивает JavaScript страницы. Страница не может свободно читать данные с другого origin. Другой origin появляется, если отличается протокол, домен или порт.

Например, https://app.example.com и https://api.example.com это разные origin. http://localhost:3000 и http://localhost:8080 тоже разные origin.

Хороший короткий ответ звучит так. CORS не делает запрос безопасным сам по себе. Он задает правила, по которым браузер решает, можно ли странице прочитать ответ от другого origin.

Как это работает в браузере

При CORS-запросе браузер добавляет заголовок Origin. Сервер должен вернуть подходящие заголовки, например Access-Control-Allow-Origin. Если origin не разрешен, браузер покажет CORS-ошибку и не отдаст ответ вашему JavaScript.

Важная деталь для интервью такая. CORS применяет браузер. Поэтому запрос из curl, Postman или с вашего backend-сервера может работать, а тот же URL из браузера падать с CORS-ошибкой.

Origin: https://app.example.com

Access-Control-Allow-Origin: https://app.example.com
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Headers: Authorization, Content-Type

Если вы говорите это на интервью, добавьте практический вывод. Источник проблемы обычно в CORS-контракте API, gateway или reverse proxy, а не в синтаксисе fetch.

Preflight и почему ломается OPTIONS

Не каждый cross-origin запрос сразу отправляется как основной. Для не простых запросов браузер сначала делает preflight, то есть OPTIONS-запрос. Так он спрашивает сервер, разрешены ли метод и заголовки будущего запроса.

Пример запроса, который обычно вызовет preflight:

fetch("https://api.example.com/profile", {
  method: "PATCH",
  headers: {
    "Content-Type": "application/json",
    Authorization: "Bearer token",
  },
  body: JSON.stringify({ name: "Alex" }),
});

Здесь есть метод PATCH, JSON и Authorization. Сервер должен корректно ответить на OPTIONS. Если API возвращает 404, 500 или не добавляет CORS-заголовки на preflight, основной запрос браузер не отправит.

Практический вывод для UI такой. Не переводите форму в успешное состояние до ответа основного запроса. Покажите понятную ошибку, сбросьте loading и дайте повторить действие после исправления причины. Иначе пользователь увидит вечную загрузку или ложный success, хотя данные не сохранились.

Как диагностировать CORS-ошибку

Что проверить сначала

1Фронт и API отличаются протоколом, доменом или портом?
Считайте запрос cross-origin и ищите CORS-контракт на сервере.
2Есть Authorization, JSON Content-Type или метод не GET/HEAD/POST?
Ждите preflight и проверяйте ответ на OPTIONS.
3Нужны cookies или HTTP-auth?
Проверьте credentials на клиенте и конкретный origin на сервере.
4Ошибка только в браузере, но curl работает?
Это ожидаемо. curl не применяет CORS, а браузер применяет.
5Запрос меняет данные?
Не ретрайте автоматически. Сначала проверьте, ушел ли запрос на сервер, и покажите пользователю понятный error state.

В DevTools смотрите не только красную строку в консоли, но и вкладку Network. Иногда ошибка висит на OPTIONS, а не на основном запросе. Иногда основной запрос дошел до сервера, но браузер заблокировал чтение ответа.

Это важно для действий, которые меняют данные. Если POST создал заказ, а фронтенд не прочитал ответ из-за CORS, слепой retry может создать дубль. Безопаснее оставить форму в понятном error state, проверить серверные логи, идемпотентность операции и только потом повторять запрос.

Что важно для фронтенда

Практические сценарии

Локальная разработкаlocalhost -> API

Добавьте dev-origin в allowlist или используйте dev-proxy. Не отключайте безопасность API ради удобства.

Авторизацияcookies

Используйте credentials: 'include', конкретный origin и Access-Control-Allow-Credentials: true. Со звездочкой cookies не заработают.

Bearer tokenAuthorization

Заголовок вызовет preflight. Сервер должен разрешить Authorization в Access-Control-Allow-Headers.

Публичный API*

Звездочка допустима только для данных без credentials и без приватного контекста. Для пользовательских данных нужен allowlist.

Продакшен-ошибкаOPTIONS 404/500

Основной запрос может не уйти. Не переводите UI в success. Настройте обработку OPTIONS на сервере или gateway и покажите error state.

На фронтенде вы управляете только клиентской частью запроса. Например, для cookies нужно явно включить credentials:

fetch("https://api.example.com/me", {
  credentials: "include",
});

Но этого мало. Сервер должен вернуть конкретный Access-Control-Allow-Origin, а не *, и Access-Control-Allow-Credentials: true. Cookies также должны быть настроены с учетом SameSite и Secure, если это cross-site сценарий.

Плохой вариант ответа на интервью такой. Можно просто поставить mode: "no-cors". Так говорить не стоит. Этот режим не дает нормальный JSON-ответ для API. Вы получите opaque response и потеряете возможность обработать статус, тело и ошибки. В UI это часто превращается в вечный loading или общее сообщение о непонятной ошибке. Безопаснее настроить CORS на сервере, gateway или dev-proxy и явно обработать error state на клиенте.

Безопасность и ограничения

CORS не заменяет авторизацию. Если API отдает приватные данные, сервер обязан проверять сессию, токен, права пользователя и бизнес-правила. CORS только ограничивает, какие страницы в браузере могут прочитать ответ.

CORS также не является полной защитой от CSRF. В некоторых случаях браузер может отправить запрос с cookies, даже если ответ потом нельзя прочитать из JavaScript. Для опасных действий нужны дополнительные меры: SameSite, CSRF-токен, проверка Origin или Referer, а также идемпотентность там, где возможны повторы.

Сильный ответ показывает эту границу. Вы не обещаете, что CORS защищает API от всех атак, и не предлагаете открывать * в продакшене без понимания данных и credentials.

Частые ошибки

Где обычно ошибаются

Проверьте формулировки, которые звучат уверенно, но на интервью быстро выдают пробелы.

  1. 1

    Пытаться починить CORS из клиентского кода

    Заголовки Access-Control-Allow-* должны приходить в ответе сервера. Если добавить их в fetch как request headers, запрос может стать сложнее и вызвать preflight. Правильный путь такой. Договоритесь о настройке API, gateway или dev-proxy.
  2. 2

    Считать звездочку безопасной настройкой

    Access-Control-Allow-Origin: * подходит не для всех случаев. С cookies он не работает. Для приватных данных опаснее другой паттерн. Сервер отражает любой Origin и включает credentials. Безопаснее держать allowlist origin-ов и отдельно настраивать окружения.
  3. 3

    Игнорировать preflight

    Если сервер не отвечает на OPTIONS, браузер не отправит основной запрос. Это часто ломает POST с JSON, запросы с Authorization и методы PUT или DELETE. Проверяйте в DevTools не только основной запрос, но и preflight.
  4. 4

    Автоматически повторять мутацию после CORS-ошибки

    CORS-ошибка не доказывает, что сервер ничего не сделал. Простой POST мог создать заявку, а браузер только заблокировал чтение ответа. Безопаснее выключить слепой retry, показать понятный error state и сверить идемпотентность или серверные логи.
  5. 5

    Путать CORS с авторизацией

    CORS не решает, имеет ли пользователь право на данные. Он говорит браузеру, можно ли странице прочитать ответ с другого origin. Сервер все равно должен проверять токены, сессии, права доступа и CSRF-защиту там, где она нужна.
  6. 6

    Использовать no-cors как решение

    Режим no-cors обычно дает opaque response. Такой ответ нельзя нормально прочитать, проверить статус или распарсить как JSON. Для API это почти всегда маскировка проблемы, а не исправление.

Follow-up

Что могут спросить дальше

Короткие ответы на вопросы, которыми проверяют понимание CORS, preflight и настройки API.

Живые ответы

Видео с похожим вопросом

Если найдем публичные интервью с таким вопросом, добавим их сюда. Их удобно смотреть после теории, чтобы свериться с живыми ответами.

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

Содержание