Útmutatók

Hogyan javítsa a CORS-hibákat (és miért keletkeznek)

A CORS-hiba azt jelenti, hogy a webes oldala egy másik eredetről (másik domain, port vagy protokoll) próbált választ olvasni, és az a szerver nem küldött olyan fejléceket, amelyek ezt engedélyezik. A böngészők blokkolják a választ, hogy védjék a felhasználókat. A javítás a szerveren történik: visszaadja az Access-Control-Allow-Origin fejlécet az oldala eredetére, és kezeli az OPTIONS preflight kéréseket. Vagy elkerülheti a problémát úgy, hogy a kérést a saját back endjén, azonos eredeten keresztül küldi el.

Az egyik legzavarbaejtőbb hiba a webfejlesztésben, mert a kérés gyakran rendben eléri a szervert. Ez az útmutató elmagyarázza, mi történik, és hogyan javítsa az egyes változatokat.

Mit jelent az „eredet”

Az eredet a protokoll, a domain és a port kombinációja:

URLEredet
https://myapp.com/dashboardhttps://myapp.com
https://api.myapp.com/usershttps://api.myapp.com (másik aldomain, tehát másik eredet)
http://localhost:5173http://localhost:5173
http://localhost:3000http://localhost:3000 (másik port, tehát másik eredet)

A böngészők az azonos eredetű szabályt (same-origin policy) követik: az oldal JavaScriptje szabadon olvashatja a saját eredetéből érkező válaszokat, de másokéból nem. A CORS (Cross-Origin Resource Sharing) az a rendszer, amely lehetővé teszi, hogy a szerver kifejezetten engedélyezze: „a válaszaimat ezekről az eredetekről érkező oldalak olvashatják”.

Két dolog meglepi az embereket:

  • A kérés gyakran eléri a szervert. A CORS általában a kódját akadályozza meg abban, hogy olvassa a választ, nem azt, hogy a szerver megkapja a kérést. Egy POST mentődhetett, annak ellenére, hogy hibát lát.
  • Csak a böngészők érvényesítik. A curl, a Postman és a szerveroldali kód teljesen figyelmen kívül hagyja a CORS-t. Ezért a „Postmanben működik” semmit nem mond a CORS-ról.

1. lépés: Olvassa el a pontos hibát

Nyissa meg a fejlesztői eszközöket (jobb klikk → Vizsgálat), menjen a Konzol fülre, és olvassa el a teljes üzenetet. A Chrome megfogalmazása megmondja, milyen problémája van:

Az üzenet tartalmazzaMi a hiba
No 'Access-Control-Allow-Origin' header is presentA szerver egyáltalán nem küldte a fejlécet, vagy a kérés már azelőtt megbukott, hogy elérte volna a CORS-kódját (például 404 vagy 500)
The 'Access-Control-Allow-Origin' header has a value '...' that is not equal to the supplied originA szerver más eredetet engedélyez, mint az Öné
Response to preflight request doesn't pass access control checkAz OPTIONS preflight megbukott
...must not be the wildcard '*' when the request's credentials mode is 'include'Sütiket küld, a szerver pedig *-gal válaszolt
Request header field authorization is not allowedA szerver nem sorolta fel ezt a fejlécet az Access-Control-Allow-Headers-ben

Aztán nyissa meg a Hálózat fület, keresse meg a hibás kérést (és az előtte lévő OPTIONS kérést), és nézze meg a státuskódját és a válaszfejléceit.

Először a státuskódot ellenőrizze. Sok „CORS-hiba” valójában szerverhiba álruhában. Ha a szerver összeomlik vagy 404-et ad, a hibaválasza gyakran nem tartalmaz CORS-fejléceket, ezért a böngésző CORS-hibát jelent a valódi probléma helyett. Javítsa az 500-as vagy 404-es hibát, és a CORS-hiba is eltűnhet.

2. lépés: Döntse el, hogy egyáltalán a böngészőből kell-e hívnia azt az API-t

Mielőtt fejléceket adna hozzá, kérdezze meg: a böngészőnek közvetlenül kellene hívnia ezt az API-t?

  • Harmadik féltől származó API, amely titkos kulcsot igényel (OpenAI, Stripe titkos kulcs, a legtöbb e-mail szolgáltatás) soha ne hívódjon a böngészőből. A kulcs minden látogató számára látható lenne. Hívja a back endjéről, és a CORS-probléma eltűnik, mert a szerver-szerver kéréseket nem érinti a CORS. Lásd: hogyan őrizze biztonságban az API-kulcsait.
  • Olyan harmadik féltől származó API, amelyet nem Ön irányít, és nem küld CORS-fejléceket, a Ön oldaláról nem javítható. Hívja a back endjéről.
  • Az Ön saját API-ját be lehet állítani helyesen. Folytassa lent.

3. lépés: Javítsa a szerveren

A szervernek a megfelelő fejléceket kell hozzáadnia a válaszaihoz, beleértve a hibaválaszokat is.

A tényleges kérésnél küldje:

  • Access-Control-Allow-Origin: https://myapp.com (a front end pontos eredete, záró perjel nélkül)
  • Vary: Origin, ha az érték attól függ, melyik eredet kérte

Az OPTIONS preflight kérésnél sikeres státuszt adjon (200 vagy 204), és:

  • Access-Control-Allow-Origin: https://myapp.com
  • Access-Control-Allow-Methods: GET, POST, PUT, PATCH, DELETE
  • Access-Control-Allow-Headers: Content-Type, Authorization (minden egyéni fejléc, amelyet küld)
  • Opcionálisan Access-Control-Max-Age: 600, hogy a böngésző egy ideig gyorsítótárazza a preflightot

A legtöbb keretrendszernek van csomagja vagy beállítása, amely ezt elvégzi. Expressben a cors csomag; FastAPI-ban a CORSMiddleware; ASP.NET Core-ban az AddCors; Springben a @CrossOrigin vagy egy CORS-konfiguráció. Tipikus Express-beállítás:

import cors from "cors";

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

A CORS-kezelést a végpontok és a hitelesítés elé tegye, hogy a preflight kérések (amelyek nem hordoznak bejelentkezést) ne utasítódjanak el 401-gyel.

AI-építőnél pontosan írja le a beállítást:

A https://myapp.com front end a https://api.myapp.com API-t hívja, és a „Response to preflight request doesn't pass access control check” hibát kapja. Állítsa be a CORS-t az API-n úgy, hogy pontosan a https://myapp.com-ot és az előnézeti eredetet engedélyezze, engedélyezze a GET, POST, PATCH, DELETE metódusokat a Content-Type és Authorization fejlécekkel, kezelje az OPTIONS kérést a hitelesítés előtt, és a hibaválaszokon is adja meg a CORS-fejléceket.

4. lépés: Kezelje a sütiket és a hitelesítő adatokat

Ha a front end sütiket (például egy bejelentkezési munkamenetet) küld egy másik eredetnek, mindkét oldalnak egyeznie kell:

  • A front end credentials: "include" beállítást ad a fetch-nek, vagy withCredentials: true-t az axiosban.
  • A szerver Access-Control-Allow-Credentials: true fejlécet küld.
  • A szerver Access-Control-Allow-Origin értéke a pontos eredet legyen, nem *.

Az oldalak közötti sütikhez SameSite=None; Secure beállítás is kell, és egyes böngészők tovább korlátozzák a harmadik féltől származó sütiket. Ez még egy ok, amiért az 5. lépésben leírt megközelítést részesítse előnyben.

5. lépés: Kerülje el a CORS-t azonos eredetű beállítással

Gyakran a legtisztább megoldás az, hogy egyáltalán nem küld eredetek közötti kéréseket. Szolgálja ki az API-t ugyanarról az eredetről, mint az oldalt, például a https://myapp.com/api/... címen:

  • Fejlesztés közben a legtöbb fejlesztői szerver tud proxyzni. A Vite server.proxy beállítása továbbíthatja a /api-t egy másik porton futó back endre, így a böngésző csak egy eredettel kommunikál.
  • Élesben irányítsa az /api-t a back endre a hoszt rewrite- vagy proxybeállításaival, vagy szolgálja ki a front endet és az API-t egy szerverről.

A front end ekkor relatív útvonalat hív, például a fetch("/api/orders")-t. Nincs eredetek közötti kérés, nincs eredetek közötti preflight, és nincs süti-gond. Azt is jelenti, hogy nem kell beégetett API-domaint használnia, amely az előnézet és az éles környezet között eltér.

Módosítsa a front endet úgy, hogy a back endet relatív /api útvonalakon hívja, teljes URL helyett, és állítson be fejlesztői proxyt, hogy az /api a API-szerverre továbbítódjon. Ezután távolítsa el azokat a CORS-beállításokat, amelyekre már nincs szükség.

Amit ne tegyen

  • mode: "no-cors" a fetch-ben. Semmit nem kerül meg; üres, olvashatatlan választ ad a kódjának.
  • Böngészőbővítmények, amelyek kikapcsolják a CORS-t. Csak az Ön böngészőjét változtatják meg. Minden látogató továbbra is látja a hibát.
  • Nyilvános „CORS-proxy” szolgáltatások valódi appokhoz. Mindent olvashatnak és módosíthatnak, ami rajtuk keresztül halad, és leállhatnak.
  • Access-Control-Allow-Origin: * olyan API-n, amely bejelentkezést használ. Hitelesítő adatokkal úgysem működik, és privát adatokhoz rossz alapértelmezés.
  • Bármely Origin fejléc visszatükrözése engedélyezett hitelesítő adatokkal. Ez bármely weboldalnak lehetővé teszi, hogy a felhasználóinak nevében bejelentkezett kéréseket tegyen. Használjon engedélyezési listát.

Gyakori okok AI-val épített appokban

HelyzetJavítás
A front end harmadik féltől származó API-t hív titkos kulccsalA hívás áthelyezése a back endre
Az előnézetben működik, a közzétett domainen nemA közzétett és az egyéni domain eredetét felvenni az engedélyezési listára, vagy relatív /api útvonalakat használni
Csak POST, PUT vagy DELETE esetén hibaA preflight nincs kezelve; adjon hozzá OPTIONS-kezelést és engedélyezett fejléceket
A hiba a bejelentkezés hozzáadása után jelent megA hitelesítő adatokhoz pontos eredet és Allow-Credentials kell
„CORS-hiba”, de a Hálózat fülön 500 látszikElőbb a szerverhibát javítsa
Az API URL localhost-ra van beégetveRelatív útvonalak vagy környezetenkénti beállítás használata

CORS a Mythexben

Ha egy Mythex-projektnek van webhelye és API-szervere, mindkettő szolgáltatásként fut ugyanabban a projektben, és az előnézetben válthat közöttük. Ha az ügynöktől azt kéri, hogy a front end a back endet relatív /api útvonalon, fejlesztés közben proxyn keresztül hívja, az a legtöbb CORS-problémát elkerüli. Ha mégis eredetek közötti hívásokra van szüksége, adja meg az ügynöknek a konzolban látott pontos hibát és az érintett eredeteket. Ellenőrizze az eredményt a közzétett appon is, mert annak címe eltér az előnézettől. Lásd: Többszolgáltatásos appok és API back endek a dokumentációban, valamint a hogyan hibakeressen AI-val épített appot és a front end vs. back end útmutatóink.

CORS-ellenőrzőlista

  • Elolvastam a teljes konzolhibát és a hibás kérés státuszkódját
  • Kizártam a rejtett 404-et vagy 500-at
  • A titkos kulcsos API-kat a back endről hívom, nem a böngészőből
  • A szerver Access-Control-Allow-Origin fejlécet küld pontos engedélyezett eredetekkel
  • Az OPTIONS preflight engedélyezett metódusokkal és fejlécekkel, a hitelesítés előtt válaszol
  • A CORS-fejlécek a hibaválaszokon is jelen vannak
  • Hitelesítő adatok: pontos eredet, Allow-Credentials: true, helyes süti-beállítások
  • Az előnézeti, a közzétett és az egyéni domain eredete is le van fedve, vagy relatív /api útvonalakat használok
  • Nincs no-cors, nyilvános proxy vagy bármely eredet visszatükrözése

Kérdések

Mit jelent a CORS-hiba?

Az oldala, amely az egyik eredetről töltődött be, egy másik eredetről próbált választ olvasni, és az a szerver nem küldött olyan fejléceket, amelyek ezt engedélyeznék. A böngésző blokkolja, hogy a kódja olvassa a választ. A javítás a szerveren van, vagy abban, hogyan irányítja a kérést, nem a front end kódban.

Kijavíthatom a CORS-hibát a front enden?

Nem igazán. Az olyan beállítások, mint a mode: 'no-cors', csak elrejtik a választ a kódja elől. Úgy javíthatja, hogy a szerver a megfelelő Access-Control-Allow-Origin fejlécet küldje, vagy hogy az API-t a saját back endjéről vagy azonos eredetű proxyn keresztül hívja.

Biztonságos az Access-Control-Allow-Origin: *?

Rendben van olyan nyilvános adatokhoz, amelyeket bárki olvashat, például egy bejelentkezés nélküli nyilvános API-hoz. Nem használható sütikkel vagy más hitelesítő adatokkal, és privát API-k esetén pontosan fel kell sorolnia az engedélyezett eredeteket.

Miért működik a kérés Postmanben vagy curl-ben, de a böngészőben nem?

A CORS-t csak a böngészők érvényesítik. Az olyan eszközök, mint a Postman és a curl, nem alkalmazzák, ezért egy kérés ott sikeres lehet, miközben az oldal JavaScriptje által küldve blokkolódik.

Mi az a preflight kérés?

Nem egyszerű kérések esetén, például egy JSON POST vagy egy Authorization fejléccel rendelkező kérés esetén a böngésző először OPTIONS kérést küld, amellyel megkérdezi a szervert, mely metódusok és fejlécek engedélyezettek. Ha ez az OPTIONS kérés hibás, vagy hiányoznak a megfelelő fejlécek, a valódi kérés el sem megy.

Mythex · Pricing · Építs bármit AI-val · Weboldal- és alkalmazássablonok · A Mythex összehasonlítva · AI-alapú alkalmazásépítési szószedet · Ingyenes eszközök AI-alapú alkalmazásépítéshez · English

English አማርኛ العربية Български বাংলা Bosanski Català Čeština Dansk Deutsch Ελληνικά Español Español (España) Eesti فارسی Suomi Français Français (Canada) ગુજરાતી हिन्दी Hrvatski Հայերեն 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 简体中文 繁體中文(香港) 繁體中文(台灣)