Представьте: вы разрабатываете фронтенд на localhost:3000, а бэкенд API — на api.yourservice.com. Все готово, вы отправляете запрос, но в консоли ошибка:
No ‘Access-Control-Allow-Origin’ header is present on the requested resource.
Знакомо? Это не баг вашего кода. Это CORS — механизм безопасности, который защищает пользователей от утечек данных. Но почему он мешает вашей работе и как его правильно настроить?
Что такое CORS и зачем он нужен
Если вы когда-нибудь задавались вопросом: «CORS — что это?» — вот простой ответ: это механизм доверия между источниками.
CORS (Cross-Origin Resource Sharing) — это способ, которым браузер решает: можно ли вашему сайту читать данные с другого домена. Он не запрещает cross-origin-запросы, а дает серверу право разрешить их.
Раньше действовала строгая политика одинакового источника (Same-Origin Policy): скрипт с site.com не мог обращаться к API на api.site.com. Это защищало от атак, но мешало разработке. CORS стал компромиссом — безопасным и гибким.
Простая аналогия: CORS как охранник у двери. Он не пускает всех подряд, но если у вас есть пропуск (правильный заголовок) — вы проходите.
Что такое источник — и когда возникает конфликт
Источник (origin) определяется тремя факторами:
- протокол (http или https),
- домен (example.com),
- порт (:80, :3000 и т. д.).
Если хоть один отличается — источники разные.
Когда фронтенд и бэкенд на разных origin — браузер включает CORS.
Ошибка No Access-Control-Allow-Origin
Это самая частая ошибка при работе с API. Причина проста: сервер не сказал браузеру: «Можно!»
Браузер отправляет ваш запрос — сервер его получает и даже обрабатывает. Но если в ответе нет заголовка Access-Control-Allow-Origin, браузер прячет ответ от JavaScript.
Важно: CORS блокирует ответ, а не запрос. Сервер все равно получает данные — но ваш код не увидит результата.
CORS-заголовки: какие они и зачем нужны
Чтобы разрешить запрос, сервер должен отдать специальные заголовки. Вот основные:
- Access-Control-Allow-Origin: https://ваш-сайт.com
- Access-Control-Allow-Methods: GET, POST, OPTIONS
- Access-Control-Allow-Headers: Content-Type
Когда можно использовать * ?
- Публичный API без авторизации.
- Никогда — если используете куки или JWT в заголовках.
Совет: никогда не ставьте Access-Control-Allow-Origin: * в продакшене, если ваш API требует авторизацию. Это открывает доступ всем — включая злоумышленников.
Preflight-запросы: почему браузер шлет OPTIONS
Когда вы отправляете «простой» запрос (GET с text/plain), CORS не мешает.
Но если вы используете:
- POST с Content-Type: application/json,
- кастомные заголовки (Authorization, X-API-Key),
браузер сначала отправит preflight-запрос методом OPTIONS.
Он спрашивает сервер:
- Можно ли делать POST с JSON?
- Разрешен ли заголовок Authorization?
Если сервер не отвечает на OPTIONS — основной запрос не отправится.
Практика: в Django (DRF) используйте пакет django-cors-headers. В FastAPI — встроенный middleware. Они автоматически обрабатывают preflight.
Как настроить CORS на сервере — быстро и безопасно
Для Django (DRF):
# settings.py CORS_ALLOWED_ORIGINS = ["https://ваш-сайт.com"] CORS_ALLOW_CREDENTIALS = True
Для FastAPI:
app.add_middleware( CORSMiddleware, allow_origins=["https://ваш-сайт.com"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], )
Лучшая практика: указывайте точные origin, а не *.
Как обойти CORS во время разработки (безопасно!)
На этапе разработки фронтенд (localhost:3000) и бэкенд (localhost:8000) — разные origin.
Правильное решение — настроить proxy в сборке:
// Код на JavaScript // vite.config.js export default { server: { proxy: { '/api': 'http://localhost:8000' } } }
Теперь все запросы к /api идут на бэкенд, но origin остается один — и CORS не срабатывает.
Не используйте расширения вроде CORS Unblock — они отключают защиту и не решают проблему на продакшене.
Распространенные ошибки и как их избежать
CORS — коротко о главном
- CORS — механизм безопасности браузера, который контролирует доступ к данным между разными источниками.
- Ошибка No ‘Access-Control-Allow-Origin’ означает: сервер не разрешил чтение данных.
- Preflight-запросы (OPTIONS) появляются при «сложных» запросах (JSON, кастомные заголовки).
- Никогда не используйте *, если ваш API требует авторизацию.
- Правильная настройка CORS — признак зрелого и безопасного backend-приложения.
- Во время разработки используйте proxy, а не отключайте безопасность.
