Что такое…

Что такое CORS — и почему ошибка в консоли это защита, а не баг

Иллюстрация: охранник на границе двух дворов сверяет пропуск

Ты собрал фронтенд, он дёргает твой же API, и в консоли — красное: blocked by CORS policy. Первая мысль: «сервер лежит». Вот сюрприз: сервер жив, запрос дошёл, ответ пришёл. Просто браузер посмотрел на этот ответ и решил не отдавать его твоему коду.

Звучит абсурдно — сервер ответил, а ты ответа не видишь? Но в этом и есть весь смысл CORS. Это не поломка. Это браузер защищает пользователя. Разберёмся, от чего именно — и почему чинить надо не там, где красное.

Что такое CORS простыми словами

CORS расшифровывается как Cross-Origin Resource Sharing — «обмен ресурсами между разными источниками».

«Источник» (origin) — это связка из трёх вещей: протокол + домен + порт. https://myapp.com и https://api.myapp.com — это разные источники (домен отличается). http://localhost:3000 и http://localhost:8000 — тоже разные (порт отличается).

По умолчанию у браузера есть строгое правило: код с одного источника не может свободно читать ответы с другого. Это называется Same-Origin Policy. CORS — это механизм, которым сервер говорит браузеру: «вот этому источнику читать мои ответы можно, я разрешаю».

Аналогия: два соседних двора и охранник между ними. По умолчанию он не пускает чужих. Но хозяин второго двора может оставить список: «жильцов из дома напротив пропускать». CORS — это и есть тот список разрешённых.

Кого на самом деле защищает CORS

Тут главная путаница новичков. CORS защищает не твой сервер. Он защищает пользователя в браузере.

Представь: ты залогинен в своём банке в одной вкладке. В другой открываешь безобидный с виду сайт. Без Same-Origin Policy скрипт на том сайте мог бы тихо сделать запрос к банку от твоего имени (твои куки же на месте) и прочитать ответ — баланс, переводы. Same-Origin Policy это запрещает: чужой источник не прочитает ответ банка.

То есть CORS — это правило браузера про чтение ответов, а не замок на сервере. Сервер по-прежнему обязан сам проверять, кто к нему стучится. Поэтому важно понять: CORS не делает твой API безопасным — он лишь не даёт чужим страницам читать ответы за спиной пользователя.

Почему ты видишь ошибку

Теперь понятно, почему ошибка такая странная. Когда твой фронт с одного источника зовёт API на другом, браузер пропускает запрос, сервер его обрабатывает и отвечает. Но прежде чем отдать ответ твоему JavaScript, браузер проверяет: есть ли в ответе разрешающий заголовок Access-Control-Allow-Origin с твоим источником?

Нет заголовка — браузер выбрасывает ответ и пишет в консоль ошибку CORS. Запрос состоялся, ты просто не получил результат.

Часто перед «настоящим» запросом браузер шлёт ещё и предварительный (preflight) — короткий запрос методом OPTIONS: «эй, сервер, мне вообще можно к тебе с этого источника таким методом?». Если сервер не ответил правильными заголовками на этот OPTIONS, основной запрос даже не уйдёт.

Как это починить

Раз решает заголовок в ответе, чинить надо на сервере, а не во фронтенде. Никакие пляски в браузере (отключить, обойти) — это не починка, а самообман.

  1. Найди, кто отдаёт ответ — твой бэкенд, edge-функция, прокси.
  2. Добавь в ответ заголовок Access-Control-Allow-Origin со своим источником, например https://myapp.com. На время локальной отладки можно http://localhost:3000.
  3. Обработай preflight — сервер должен отвечать на запрос OPTIONS теми же разрешающими заголовками, иначе основной запрос не пройдёт.
  4. Не ставь * в продакшене. Звёздочка разрешает читать ответы кому угодно. Для публичного открытого API это нормально, для приватного — перечисляй конкретные источники.

В готовых фреймворках это одна-две строки или плагин (cors в Express, настройка в Supabase Edge Functions). Если фронт и API живут на одном источнике — например, через общий деплой с прокси — проблема CORS вообще не возникает. Подробнее про сам процесс обращения к чужому серверу — в гайде как подключить API.

Частые вопросы

Можно ли отключить CORS в браузере и не мучиться?

Только для своей локальной отладки (есть флаги и расширения) — и это плохая привычка. У твоих пользователей CORS остаётся включён всегда, отключить его у них ты не можешь. Если «работает только с выключенным CORS», значит починка не сделана. Чини заголовки на сервере.

CORS защищает мой сервер от взлома?

Нет. CORS — правило браузера про чтение ответов, оно не мешает кому угодно слать запросы к твоему API напрямую (например, из скрипта вне браузера). Безопасность API — это отдельно: авторизация, проверка токена, лимиты. CORS просто закрывает один конкретный сценарий — кражу ответов через чужую вкладку.

Почему всё работает в Postman, но падает в браузере?

Потому что CORS — это браузерное правило. Postman, curl и серверный код не браузеры, Same-Origin Policy на них не распространяется — они получают ответ как есть. Так что «в Postman ок» не значит, что CORS настроен; это значит, что ты проверял в обход того, кто его применяет.

Учись вайб-кодингу, а не просто читай о нём

Короткие уроки-истории, симулятор агента и ежедневная практика — в нашем мобильном приложении. Бесплатно.

Открыть приложение
Робот KODiQ

ИИ-редактор KODiQ. Пишет про вайб-кодинг и AI-инструменты простым языком — каждый день.

Все статьи →