#Что означает ошибка
CORS
CORS (Cross-Origin Resource Sharing) — механизм браузера, который запрещает странице с одного источника (схема + домен + порт) читать ответы другого источника, если тот явно не разрешил это заголовками. Ошибка «No Access-Control-Allow-Origin header» означает, что сервер не прислал нужный заголовок, и браузер заблокировал доступ скрипта к ответу.
Важно: запрос на сервер при этом обычно доходит и даже обрабатывается — браузер блокирует только чтение ответа. Поэтому исправлять CORS нужно на стороне сервера, а не в клиентском JavaScript. Никакие настройки fetch не обойдут запрет, кроме режима no-cors, который возвращает «непрозрачный» ответ без данных.
Настройте заголовки CORS на сервере и обработку preflight.
#Причины и решения
| Возможная причина | Как узнать | Что делать |
|---|---|---|
| Нет заголовкаСервер. | Проявляется как «CORS» или близкий по смыслу сбой. | Добавьте. |
| PreflightOPTIONS. | Проявляется как «CORS» или близкий по смыслу сбой. | Обработайте. |
| КреденшалыРежим. | Проявляется как «CORS» или близкий по смыслу сбой. | Укажите origin. |
| ПроксиDev. | Проявляется как «CORS» или близкий по смыслу сбой. | Настройте. |
#Кратко: причина, признак, действие
| Причина | Как узнать | Что делать |
|---|---|---|
| Отсутствует разрешение источника | В ответе на запрос нет Access-Control-Allow-Origin или он не совпадает с Origin страницы | На своём API разрешите точный адрес фронтенда; проверьте HTTPS, порт и Vary: Origin при динамическом выборе. |
| Предварительный запрос OPTIONS не проходит | В Network виден OPTIONS с 401/403/405 или без CORS-заголовков | Настройте ответ на OPTIONS и Access-Control-Allow-Methods / Access-Control-Allow-Headers. |
| Cookie в межсайтовом запросе | Клиент задаёт credentials: include, но разрешение возвращает звёздочку | Укажите конкретный Origin, Access-Control-Allow-Credentials: true и проверьте атрибуты cookie. |
| Сеть, сертификат или прокси | В Network нет ответа либо ошибка DNS/TLS; Console может выглядеть как CORS | Сначала устраните сетевой/TLS-сбой, затем диагностируйте CORS. |
#Пошаговое решение
- Откройте инструменты разработчика и найдите запросВ браузере Chrome/Edge нажмите F12 (либо Ctrl+Shift+I) → вкладка Network («Сеть»), поставьте отметку Preserve log («Сохранять журнал») при необходимости и обновите страницу. Нажмите строку неудачного запроса: запишите Request URL, Request Method, статус ответа и Origin в заголовках запроса. В Console найдите полный текст ошибки. Если запрос не дошёл до сервера из-за DNS/TLS, правка CORS его не исправит.
- Определите владельца сервера APIПосмотрите, к какому домену обращается страница. Если это чужой API, вы не можете разрешить его CORS из клиентского JavaScript: используйте официальный способ авторизации API либо собственный сервер-посредник с соблюдением правил сервиса. Не устанавливайте расширения браузера для отключения CORS и не запускайте браузер с выключенной веб-защитой.
- Разрешите конкретный адрес сайта на своём сервереЕсли API под вашим управлением, настройте сервер так, чтобы ответ на разрешённый запрос содержал
Access-Control-Allow-Origin: https://example.com(вместоhttps://example.comукажите фактический Origin сайта, включая протокол и порт). В Express установите серверную библиотеку в каталоге проекта командойnpm install cors; в коде сервера подключитеcorsдо маршрутов и разрешите только доверенные адреса. Не копируйте*, если передаются cookie или другие учётные данные. - Обработайте предварительный запрос OPTIONSЕсли браузер отправляет запрос с
Authorization,Content-Type: application/jsonили нестандартными заголовками, во вкладке Network найдите сначалаOPTIONS. Сервер должен разрешить нужный метод вAccess-Control-Allow-Methodsи фактические заголовки вAccess-Control-Allow-Headers, а также корректно ответить на OPTIONS. Проверьте, что запрос не перенаправляется на вход и не блокируется прокси. Не добавляйте заголовки только в ответ основногоGET/POST. - Отдельно проверьте запросы с cookieЕсли клиент использует
fetch(url, { credentials: "include" }), сервер должен вернуть точный разрешённый Origin иAccess-Control-Allow-Credentials: true;Access-Control-Allow-Origin: *здесь недопустим. Проверьте такжеSameSiteиSecureу cookie и политику браузера: одних CORS-заголовков для межсайтовой авторизации бывает недостаточно. - Проверьте исправление в браузереПерезапустите ваш сервер/API, если изменилась конфигурация, очистите старые записи Network и повторите действие. В ответе OPTIONS (если он был) и итоговом ответе должны присутствовать соответствующие разрешения; в Console не должно быть ошибки CORS. Если ответ 401/403, это уже ошибка авторизации, а не повод разрешать любой источник. При отсутствии доступа к серверу передайте разработчику API Origin, метод и названия заголовков без токенов.
#Что такое preflight
Для «непростых» запросов (методы PUT, DELETE, нестандартные заголовки, JSON в Content-Type) браузер сначала отправляет предварительный запрос OPTIONS. Сервер должен ответить статусом 200/204 и заголовками Access-Control-Allow-Methods и Access-Control-Allow-Headers. Если OPTIONS обрабатывается как неизвестный маршрут или блокируется авторизацией, запрос не пройдёт.
#Как настроить правильно
Возвращайте Access-Control-Allow-Origin с точным доменом клиента, а не звёздочкой, если используются cookie или заголовок Authorization; в этом случае добавьте Access-Control-Allow-Credentials: true. Заголовок Vary: Origin нужен, чтобы кеши не путали ответы. Не отражайте произвольный Origin без проверки — это уязвимость.
#Временные решения для разработки
В локальной разработке настройте прокси Vite или webpack-dev-server так, чтобы браузер обращался к своему источнику, а сервер разработки перенаправлял запросы к API. Не устанавливайте расширения, отключающие CORS: они скрывают проблему и ухудшают безопасность браузера.
nginx -t до перезагрузки; пример не предназначен для вставки без проверки в произвольный блок Nginx.location /api/ { add_header Access-Control-Allow-Origin "https://app.example.com" always; add_header Access-Control-Allow-Methods "GET, POST, OPTIONS" always; add_header Access-Control-Allow-Headers "Authorization, Content-Type" always; if ($request_method = OPTIONS) { return 204; }}Команда может изменить состояние системы или её настройки. Проверьте параметры и последствия перед запуском.