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:
| URL | Eredet |
|---|---|
https://myapp.com/dashboard | https://myapp.com |
https://api.myapp.com/users | https://api.myapp.com (másik aldomain, tehát másik eredet) |
http://localhost:5173 | http://localhost:5173 |
http://localhost:3000 | http://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 tartalmazza | Mi a hiba |
|---|---|
No 'Access-Control-Allow-Origin' header is present | A 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 origin | A szerver más eredetet engedélyez, mint az Öné |
Response to preflight request doesn't pass access control check | Az 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 allowed | A 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.comAccess-Control-Allow-Methods: GET, POST, PUT, PATCH, DELETEAccess-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.comfront end ahttps://api.myapp.comAPI-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 ahttps://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 afetch-nek, vagywithCredentials: true-t az axiosban. - A szerver
Access-Control-Allow-Credentials: truefejlé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.proxybeá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"afetch-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
Originfejlé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
| Helyzet | Javítás |
|---|---|
| A front end harmadik féltől származó API-t hív titkos kulccsal | A hívás áthelyezése a back endre |
| Az előnézetben működik, a közzétett domainen nem | A 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 hiba | A preflight nincs kezelve; adjon hozzá OPTIONS-kezelést és engedélyezett fejléceket |
| A hiba a bejelentkezés hozzáadása után jelent meg | A hitelesítő adatokhoz pontos eredet és Allow-Credentials kell |
| „CORS-hiba”, de a Hálózat fülön 500 látszik | Előbb a szerverhibát javítsa |
Az API URL localhost-ra van beégetve | Relatí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-Originfejlé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.