Разработка

Как исправить ошибки CORS

“Blocked by CORS policy” — это защита ваших пользователей со стороны браузера, а не ошибка в вашем коде. Исправление всегда делается на сервере, который принимает запрос. В этом руководстве объясняется, что проверяет браузер, и приводятся рабочие конфигурации для типичных случаев.

Средний · Чтение: 9 мин · Обновлено 30 октября 2026 г.

Как исправить ошибки CORS

Что такое CORS на самом деле

Браузеры запрещают JavaScript на https://app.example.com читать ответы от другого origin (схема + хост + порт), например https://api.example.com, если сервер не разрешил это. Сервер делает это с помощью заголовков ответа Access-Control-Allow-*. Запросы из curl, Postman или вашего бэкенда не затрагиваются, поэтому «в Postman работает», а в браузере нет.

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

  • “No ‘Access-Control-Allow-Origin’ header is present” — сервер вообще не отправил заголовки CORS или вернул страницу ошибки (404, 500) без них.
  • “Response to preflight request doesn’t pass access control check” — запрос OPTIONS завершился с ошибкой: он не был обработан, вернул ошибку или не содержал нужных заголовков.
  • “The value of the ‘Access-Control-Allow-Origin’ header must not be the wildcard ‘*’ when credentials mode is ‘include’” — вы отправляете cookies, поэтому сервер должен вернуть точный origin, а не звездочку.

Посмотрите неудачный запрос в DevTools → Network или проверьте реальные заголовки ответа с помощью HTTP Header Checker.

Простые запросы и preflight

Запрос считается «простым», если это GET, HEAD или POST только с базовыми заголовками и телом в формате формы или простого текста. Всё остальное — Content-Type: application/json, заголовок Authorization, PUT или DELETE — заставляет браузер сначала отправить OPTIONS-запрос preflight. Ваш сервер должен ответить на него статусом 204 или 200 и такими заголовками:

Access-Control-Allow-Origin: https://app.example.com
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Headers: Content-Type, Authorization
Access-Control-Max-Age: 600

Рабочие конфигурации

Express с пакетом cors:

const cors = require('cors');
app.use(cors({
  origin: ['https://app.example.com'],
  credentials: true,                 // only if you send cookies
  methods: ['GET', 'POST', 'PUT', 'DELETE'],
}));

Nginx:

location /api/ {
  if ($request_method = OPTIONS) {
    add_header Access-Control-Allow-Origin "https://app.example.com" always;
    add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE" always;
    add_header Access-Control-Allow-Headers "Content-Type, Authorization" always;
    add_header Access-Control-Max-Age 600;
    return 204;
  }
  add_header Access-Control-Allow-Origin "https://app.example.com" always;
  proxy_pass http://backend;
}

Флаг always важен: без него Nginx не добавляет заголовок в ответах с ошибками, и браузер сообщает об ошибке CORS вместо реального 500. Сгенерировать заголовки для других серверов (Vercel, Netlify, Cloudflare Workers, Apache) можно с помощью CORS Header Generator.

Cookies и учетные данные

Чтобы отправлять cookies между разными origin, запрос должен содержать credentials: 'include' (fetch), а сервер должен отвечать Access-Control-Allow-Credentials: true и точным origin — никогда *. Сама cookie должна иметь SameSite=None; Secure. Если вы подставляете origin из списка, добавьте также Vary: Origin, чтобы кэши не отдавали заголовки одного сайта другому.

Чего не делать

  • Не возвращайте любой заголовок Origin обратно при включенных учетных данных — так любой сайт сможет читать данные ваших пользователей.
  • Не «исправляйте» CORS расширением браузера или публичным прокси: это только скрывает проблему на вашем компьютере.
  • Если API ваш и находится на том же сайте, обратный прокси (тот же origin) полностью убирает необходимость в CORS.

Повторите запрос браузера с помощью API Tester или превратите его в код с помощью cURL to Code.

Часто задаваемые вопросы

Можно ли исправить CORS на фронтенде?
Нет. CORS применяется браузером на основании заголовков ответа сервера. Измените сервер или направьте запрос через свой бэкенд или прокси на том же origin.
Почему работает в Postman, но не в браузере?
Postman, curl и серверы не применяют CORS — это делают только браузеры, чтобы защитить данные пользователей на других сайтах.
Безопасен ли Access-Control-Allow-Origin: *?
Для публичных API только для чтения без cookies — да. Его нельзя использовать с учетными данными, а закрытые API должны перечислять разрешенные origin.

Читайте также