Ръководства

Как да поправите CORS грешки (и защо се появяват)

CORS грешката означава, че вашата уеб страница се е опитала да прочете отговор от друг произход (друг домейн, порт или протокол), а този сървър не е изпратил заглавия, които казват, че е позволено. Браузърите блокират отговора, за да защитят потребителите. Поправяте го на сървъра – като връщате заглавие Access-Control-Allow-Origin за произхода на сайта си и обработвате OPTIONS preflight заявките – или го избягвате, като изпращате заявката през собствения си бекенд на същия произход.

Това е една от най-объркващите грешки в уеб разработката, защото заявката често стига до сървъра без проблем. Това ръководство обяснява какво се случва и как да поправите всеки вариант.

Какво е „произход“

Произходът е комбинация от протокол, домейн и порт:

URLПроизход
https://myapp.com/dashboardhttps://myapp.com
https://api.myapp.com/usershttps://api.myapp.com (различно поддомейн, значи различен произход)
http://localhost:5173http://localhost:5173
http://localhost:3000http://localhost:3000 (различен порт, значи различен произход)

Браузърите следват политиката за същия произход: JavaScript на страницата може свободно да чете отговори от собствения си произход, но не и от други. CORS (Cross-Origin Resource Sharing) е системата, с която сървърът се съгласява: „отговорите ми могат да се четат от страници с тези произходи“.

Два факта изненадват хората:

  • Заявката често стига до сървъра. CORS обикновено блокира кода ви да прочете отговора, а не сървърът да получи заявката. POST може да е записан, въпреки че сте видели грешка.
  • Прилага се само от браузърите. curl, Postman и серверен код игнорират CORS напълно. Затова „работи в Postman“ не ви казва нищо за CORS.

Стъпка 1: Прочетете точната грешка

Отворете инструментите за разработчици (десен бутон → Inspect), отидете в раздела Console и прочетете цялото съобщение. Формулировката на Chrome показва какъв проблем имате:

Съобщението съдържаКакво не е наред
No 'Access-Control-Allow-Origin' header is presentСървърът изобщо не е изпратил заглавието или заявката е провалена преди да стигне до CORS кода ви (например 404 или 500)
The 'Access-Control-Allow-Origin' header has a value '...' that is not equal to the supplied originСървърът позволява друг произход, различен от вашия
Response to preflight request doesn't pass access control checkOPTIONS preflight заявката се е провалила
...must not be the wildcard '*' when the request's credentials mode is 'include'Изпращате бисквитки, а сървърът отговаря с *
Request header field authorization is not allowedСървърът не е изброил това заглавие в Access-Control-Allow-Headers

След това отворете раздела Network, намерете провалената заявка (и всяка OPTIONS заявка преди нея) и вижте статус кода и заглавията на отговора.

Първо проверете статус кода. Много „CORS грешки“ всъщност са серверна грешка, маскирана като такава. Ако сървърът се срине или върне 404, отговорът му често няма CORS заглавия и браузърът докладва CORS, вместо истинския проблем. Поправете 500 или 404 грешката и CORS грешката може да изчезне.

Стъпка 2: Решете дали изобщо трябва браузърът да вика това API

Преди да добавяте заглавия, попитайте: трябва ли браузърът да вика това API директно?

  • Трето API, което изисква тайна ключ (OpenAI, тайният ключ на Stripe, повечето имейл услуги) никога не трябва да се вика от браузъра. Ключът ще е видим за всеки посетител. Викайте го от бекенда си и CORS проблемът изчезва, защото заявките сървър-към-сървър не подлежат на CORS. Вижте как да пазите API ключовете си в безопасност.
  • Трето API, което не контролирате и което не изпраща CORS заглавия, не може да се поправи от вашата страна. Викайте го от бекенда си.
  • Вашето собствено API може да се поправи чрез правилна конфигурация. Продължете по-долу.

Стъпка 3: Поправете на сървъра

Сървърът трябва да добавя правилните заглавия към всичките си отговори, включително тези с грешки.

За самата заявка изпратете:

  • Access-Control-Allow-Origin: https://myapp.com (точният произход на фронтенда ви, без наклонена черта в края)
  • Vary: Origin, ако стойността зависи от това кой произход пита

За preflight OPTIONS заявката отговорете със статус за успех (200 или 204) и:

  • Access-Control-Allow-Origin: https://myapp.com
  • Access-Control-Allow-Methods: GET, POST, PUT, PATCH, DELETE
  • Access-Control-Allow-Headers: Content-Type, Authorization (всяко собствено заглавие, което изпращате)
  • По желание Access-Control-Max-Age: 600, за да кешира браузърът preflight заявката известно време

Повечето фреймуърци имат пакет или настройка, която прави това. В Express – пакетът cors; във FastAPI – CORSMiddleware; в ASP.NET Core – AddCors; в Spring – @CrossOrigin или CORS конфигурация. Типична настройка в Express:

import cors from "cors";

app.use(cors({
  origin: ["https://myapp.com", "http://localhost:5173"],
  credentials: true,
}));

Поставете CORS обработката преди маршрутите и удостоверяването, за да не се отхвърлят preflight заявките (които не носят вход) с 401.

При AI конструктор опишете настройката точно:

Фронтендът на https://myapp.com вика API на https://api.myapp.com и получава „Response to preflight request doesn't pass access control check“. Конфигурирайте CORS на API-то така, че да позволява точно https://myapp.com и preview произхода, да разрешава GET, POST, PATCH, DELETE със заглавията Content-Type и Authorization, да обработва OPTIONS преди удостоверяването и да включва CORS заглавията и в отговорите с грешки.

Стъпка 4: Работа с бисквитки и удостоверителни данни

Ако фронтендът ви изпраща бисквитки (например сесия за вход) към друг произход, двете страни трябва да се съгласят:

  • Фронтендът задава credentials: "include" в fetch или withCredentials: true в axios.
  • Сървърът изпраща Access-Control-Allow-Credentials: true.
  • Access-Control-Allow-Origin на сървъра трябва да е точният произход, а не *.

Междусайтовите бисквитки също изискват SameSite=None; Secure, а някои браузъри ограничават още бисквитките от трети страни. Това е още една причина да предпочитате подхода от стъпка 5.

Стъпка 5: Избегнете CORS с настройка от същия произход

Често най-чистата поправка е да не правите междусайтови заявки изобщо. Сервирайте API-то от същия произход като страницата, например на https://myapp.com/api/...:

  • В разработка повечето dev сървъри могат да проксират. Настройката server.proxy на Vite може да препраща /api към бекенда ви на друг порт, така че браузърът говори само с един произход.
  • В продукция пренасочете /api към бекенда през настройките за пренаписване или прокси на хостинга, или сервирайте фронтенда и API-то от един сървър.

Тогава фронтендът вика относителен път като fetch("/api/orders"). Няма междусайтова заявка, няма preflight между произходи и няма проблеми с бисквитките. Освен това не закодирате в кода домейн на API, който се различава между преглед и продукция.

Променете фронтенда да вика бекенда с относителни пътища /api вместо пълен URL и настройте dev прокси, така че /api да препраща към API сървъра. После премахнете CORS настройките, които вече не са нужни.

Какво да не правите

  • mode: "no-cors" във fetch. Нищо не заобикаля; дава на кода ви празен, нечетим отговор.
  • Браузърни разширения, които изключват CORS. Те променят само вашия браузър. Всеки посетител пак вижда грешката.
  • Публични услуги „CORS прокси“ за реални приложения. Могат да четат и променят всичко, което минава през тях, и понякога спират да работят.
  • Access-Control-Allow-Origin: * за API с вход. Така или иначе не работи с удостоверителни данни и е грешното подразбиране за частни данни.
  • Връщане на произволен Origin заглавие обратно с разрешени удостоверителни данни. Това позволява на всеки сайт да прави заявки от името на логнатите ви потребители. Използвайте списък с разрешени.

Чести причини в приложения, създадени с AI

СитуацияПоправка
Фронтендът вика трето API с тайн ключПреместете заявката в бекенда
Работи в преглед, но не и в публикуваното приложениеДобавете публикувания и персоналния домейн в списъка с разрешени или използвайте относителни пътища /api
Грешка само при POST, PUT или DELETEPreflight не е обработен; добавете обработка на OPTIONS и разрешените заглавия
Грешката се появи след добавяне на входБисквитките изискват точен произход и Allow-Credentials
„CORS грешка“, но в раздела Network се вижда 500Първо поправете серверната грешка
API URL е записан твърдо като localhostИзползвайте относителни пътища или настройка за всяка среда

CORS в Mythex

Когато Mythex проект има уебсайт и API сървър, и двата работят като услуги в същия проект и можете да превключвате между тях в прегледа. Ако помолите агента фронтендът да вика бекенда през относителен път /api, проксиран при разработка, се избягват повечето CORS проблеми. Ако все пак са ви нужни междусайтови заявки, дайте на агента точната грешка от конзолата и участващите произходи. Проверете резултата и в публикуваното приложение, защото адресът му е различен от този в прегледа. Вижте Многоуслугови приложения и API бекенди в документацията, както и нашите ръководства за отстраняване на грешки в приложение, създадено с AI и фронтенд срещу бекенд.

Списък за проверка на CORS

  • Прочетена е цялата грешка от конзолата и статус кодът на провалената заявка
  • Изключена е скрита 404 или 500 грешка
  • API-та с тайни ключове се викат от бекенда, не от браузъра
  • Сървърът изпраща Access-Control-Allow-Origin с точни разрешени произходи
  • OPTIONS preflight е обработен с разрешени методи и заглавия, преди удостоверяването
  • CORS заглавията присъстват и в отговорите с грешки
  • Удостоверителни данни: точен произход, Allow-Credentials: true и правилни настройки на бисквитките
  • Покрити са произходите на преглед, публикуване и персонален домейн, или се използват относителни пътища /api
  • Няма no-cors, публични прокси или шорткъти с отразяване на произволен произход

Въпроси

Какво означава CORS грешка?

Вашата страница, заредена от един произход, се е опитала да прочете отговор от друг произход, а сървърът на този произход не е изпратил заглавки, които да го позволяват. Браузърът блокира кода ви да прочете отговора. Поправката е на сървъра или в начина, по който се насочва заявката, а не във фронтенд кода.

Мога ли да поправя CORS грешка от фронтенда?

Не по същество. Настройки като mode: 'no-cors' само скриват отговора от кода ви. Поправката е сървърът да изпраща правилното заглавие Access-Control-Allow-Origin или да извиквате API-то от собствения си бекенд или от прокси от същия произход.

Безопасно ли е Access-Control-Allow-Origin: *?

Добре е за публични данни, които всеки може да чете, например публично API без вход. Не може да се ползва с бисквитки или други удостоверителни данни, а за частни API трябва да изброите точно допустимите произходи.

Защо заявката работи в Postman или curl, но не и в браузъра?

CORS се прилага само от браузърите. Инструменти като Postman и curl не го прилагат, така че заявката може да успее там и пак да бъде блокирана, когато JavaScript на страницата я изпрати.

Какво е preflight заявка?

За заявки, които не са прости, например JSON POST или заявка със заглавие Authorization, браузърът първо изпраща OPTIONS заявка, за да попита сървъра кои методи и заглавия са разрешени. Ако тази OPTIONS заявка се провали или няма правилните заглавия, истинската заявка никога не се изпраща.

Mythex · Pricing · Създай всичко с ИИ · Шаблони за уебсайтове и приложения · Mythex в сравнение · Речник на създаването на приложения с ИИ · Безплатни инструменти за създаване на приложения с ИИ · English

English አማርኛ العربية বাংলা Bosanski Català Čeština Dansk Deutsch Ελληνικά Español Español (España) Eesti فارسی Suomi Français Français (Canada) ગુજરાતી हिन्दी Hrvatski Magyar Հայերեն Bahasa Indonesia Íslenska Italiano 日本語 ქართული Қазақ тілі ಕನ್ನಡ 한국어 Lietuvių Latviešu Македонски മലയാളം Монгол मराठी Bahasa Melayu မြန်မာ Norsk bokmål Nederlands ਪੰਜਾਬੀ Polski Português (Brasil) Português (Portugal) Română Русский Slovenčina Slovenščina Soomaali Shqip Srpski Svenska Kiswahili தமிழ் తెలుగు ไทย Tagalog Türkçe Українська اردو Tiếng Việt 简体中文 繁體中文(香港) 繁體中文(台灣)