Kuidas parandada CORS-vead (ja miks need tekivad)
CORS-viga tähendab, et su veebileht proovis lugeda vastust teisest päritolust (teisest domeenist, pordist või protokollist) ja see server ei saatnud päiseid, mis ütlevad, et see on lubatud. Brauserid blokeerivad vastuse, et kaitsta kasutajaid. Parandad selle serveris, tagastades Access-Control-Allow-Origin päise sinu saidi päritolule ja käsitledes OPTIONS preflight-päringuid. Või väldid seda, saates päringu läbi oma tagakülje samal päritolul.
See on veebiarenduses üks segasemaid vigu, sest päring jõuab sageli serverini kenasti. See juhend selgitab, mis toimub, ja kuidas parandada iga variandi.
Mida tähendab „päritolu“
Päritolu (origin) on protokolli, domeeni ja pordi kombinatsioon:
| URL | Päritolu |
|---|---|
https://myapp.com/dashboard | https://myapp.com |
https://api.myapp.com/users | https://api.myapp.com (teine alamdomeen, seega teine päritolu) |
http://localhost:5173 | http://localhost:5173 |
http://localhost:3000 | http://localhost:3000 (teine port, seega teine päritolu) |
Brauserid järgivad sama päritolu poliitikat: lehe JavaScript võib vabalt lugeda oma päritolu vastuseid, aga mitte teiste omi. CORS (Cross-Origin Resource Sharing) on süsteem, mis laseb serveril sellega nõustuda: „minu vastuseid tohivad lugeda lehed nendest päritoludest“.
Kaks tagajärge üllatavad inimesi:
- Päring jõuab sageli serverini. CORS blokeerib tavaliselt su koodi vastuse lugemise, mitte serveri päringu vastuvõtmise. POST võidi salvestada, isegi kui nägid viga.
- Ainult brauserid jõustavad seda. curl, Postman ja serveripoolne kood ignoreerivad CORS-i täielikult. Seepärast ei tähenda „töötab Postmanis“ CORS-i kohta midagi.
Samm 1: loe täpne viga
Ava arendajatööriistad (parem klõps → Inspect), mine Console vahelehele ja loe kogu sõnum. Chrome'i sõnastus näitab, millise probleemiga tegemist on:
| Sõnum sisaldab | Mis on valesti |
|---|---|
No 'Access-Control-Allow-Origin' header is present | Server ei saatnud päist üldse või päring ebaõnnestus enne su CORS-koodi jõudmist (näiteks 404 või 500) |
The 'Access-Control-Allow-Origin' header has a value '...' that is not equal to the supplied origin | Server lubab teist päritolu kui sinu oma |
Response to preflight request doesn't pass access control check | OPTIONS preflight ebaõnnestus |
...must not be the wildcard '*' when the request's credentials mode is 'include' | Saadad küpsiseid ja server vastas *-iga |
Request header field authorization is not allowed | Server ei lisanud seda päist Access-Control-Allow-Headers-i |
Seejärel ava Network vaheleht, leia ebaõnnestunud päring (ja kõik sellele eelnevad OPTIONS päringud) ning vaata selle staatusekoodi ja vastuse päiseid.
Kontrolli esmalt staatusekoodi. Paljud „CORS-vead“ on tegelikult serveri vead maskeeritud kujul. Kui server kukub või tagastab 404, ei sisalda selle veavastus sageli CORS-päiseid, seega brauser teatab CORS-ist, mitte tegelikust probleemist. Paranda 500 või 404 ja CORS-viga võib kaduda.
Samm 2: otsusta, kas brauser peaks üldse seda API-d kutsuma
Enne päiste lisamist küsi: kas brauser peaks seda API-d otse kutsuma?
- Kolmanda osapoole API, mis vajab salajast võtit (OpenAI, Stripe'i salajane võti, enamik e-posti teenuseid), ei tohiks kunagi brauserist kutsuda. Võti oleks nähtav igale külastajale. Kutsu seda oma tagakülje kaudu, ja CORS-probleem kaob, sest serverist serverisse päringud ei ole CORS-iga seotud. Vaata kuidas hoida API-võtmed turvalised.
- Kolmanda osapoole API, mida sa ei kontrolli ja mis ei saada CORS-päiseid, ei saa su poolelt parandada. Kutsu seda oma tagakülje kaudu.
- Sinu enda API saab parandada korraliku seadistamisega. Jätkame allpool.
Samm 3: paranda oma serveris
Server peab lisama õiged päised oma vastustele, sealhulgas veavastustele.
Tegeliku päringu jaoks saada:
Access-Control-Allow-Origin: https://myapp.com(sinu esilehe täpne päritolu, ilma lõppkaldkriipsuta)Vary: Origin, kui väärtus sõltub sellest, milline päritolu küsis
OPTIONS preflight-päringu jaoks vasta edukuse staatusega (200 või 204) ja:
Access-Control-Allow-Origin: https://myapp.comAccess-Control-Allow-Methods: GET, POST, PUT, PATCH, DELETEAccess-Control-Allow-Headers: Content-Type, Authorization(iga kohandatud päis, mida saadad)- Valikuliselt
Access-Control-Max-Age: 600, et brauser vahemällu preflight mõneks ajaks
Enamikul raamistikel on pakett või seade, mis seda teeb. Expressis on selleks cors-pakett; FastAPI-s CORSMiddleware; ASP.NET Core'is AddCors; Springis @CrossOrigin või CORS-konfiguratsioon. Tüüpiline Expressi seadistus:
import cors from "cors";
app.use(cors({
origin: ["https://myapp.com", "http://localhost:5173"],
credentials: true,
}));
Aseta CORS-käsitlus enne oma marsruute ja autentimist, et preflight-päringud (mis ei kanna sisselogimist) ei saaks 401-ga tagasi lükatud.
AI-ehitajaga kirjelda seadistust täpselt:
Esikülg aadressil
https://myapp.comkutsub API-d aadressilhttps://api.myapp.comja saab vea „Response to preflight request doesn't pass access control check“. Seadista API-s CORS nii, et see lubab täpselthttps://myapp.com-i ja eelvaate päritolu, lubab GET, POST, PATCH, DELETE koos päistega Content-Type ja Authorization, käsitleb OPTIONS enne autentimist ja lisab CORS-päised ka veavastustele.
Samm 4: käsitle küpsiseid ja mandaate
Kui su esikülg saadab küpsiseid (näiteks sisselogimise sessiooni) teise päritolu poole, peavad mõlemad pooled kokku leppima:
- Esikülg seab
fetch-ilcredentials: "include"või axios'iswithCredentials: true. - Server saadab
Access-Control-Allow-Credentials: true. - Serveri
Access-Control-Allow-Originpeab olema täpne päritolu, mitte*.
Saitidevahelised küpsised vajavad ka SameSite=None; Secure märgistust ning mõned brauserid piiravad kolmanda osapoole küpsiseid veelgi. See on veel üks põhjus eelistada Sammu 5 lähenemist.
Samm 5: väldi CORS-i samapäritolu seadistusega
Sageli on puhtaim lahendus mitte teha päritolude vahelisi päringuid üldse. Serveeri API samalt päritolult kui leht, näiteks aadressil https://myapp.com/api/...:
- Arenduses saavad enamik arendusserverid proxy'da. Vite'i
server.proxyseade võib suunata/apisinu tagakülje teisele pordile, nii et brauser räägib alati ainult ühe päritoluga. - Tootmises suuna
/apitagakülje poole hosti ümbersuunamis- või proxy-seadete kaudu või serveeri esikülg ja API ühelt serverilt.
Esikülg kutsub siis suhtelist teed, nagu fetch("/api/orders"). Päritolude vahelist päringut pole, päritolude vahelist preflight'i pole ega küpsiste peavalu. See tähendab ka, et ei pea kõvasti kodeerima API domeeni, mis erineb eelvaates ja tootmises.
Muuda esikülg kutsuma tagakülge suhteliste /api teedega täieliku URL-i asemel ja seadista arendusproxy, mis suunab /api API-serverisse. Seejärel eemalda kõik CORS-seaded, mida enam vaja pole.
Mida mitte teha
mode: "no-cors"fetch-is. See ei möödu millestki; see annab su koodile tühja, loetamatu vastuse.- Brauserilaiendid, mis keelavad CORS-i. Need muudavad ainult sinu brauserit. Iga külastaja näeb endiselt viga.
- Avalikud „CORS-proxy“ teenused päris äppide jaoks. Need saavad lugeda ja muuta kõike, mis neist läbi käib, ja need kukuvad.
Access-Control-Allow-Origin: *API-l, mis kasutab sisselogimist. See ei tööta mandaatidega niikuinii ja on privaatsete andmete jaoks vale vaikeväärtus.- Mis tahes
Origin-päise tagasipeegeldamine mandaatidega lubatuna. See laseb mis tahes veebisaidil teha sisselogitud päringuid su kasutajate nimel. Kasuta lubatud nimekirja.
Levinud põhjused AI-ehitatud äppides
| Olukord | Parandus |
|---|---|
| Esikülg kutsub kolmanda osapoole API-d salajase võtmega | Vii kutse tagakülge |
| Töötab eelvaates, ebaõnnestub avaldatud domeenil | Lisa avaldatud ja kohandatud domeeni päritolud lubatud nimekirja või kasuta suhtelisi /api teid |
| Viga ainult POST, PUT või DELETE puhul | Preflight pole käsitletud; lisa OPTIONS käsitlus ja lubatud päised |
| Viga ilmus pärast sisselogimise lisamist | Mandaadid vajavad täpset päritolu ja Allow-Credentials |
| „CORS-viga“, aga Network vaheleht näitab 500 | Paranda kõigepealt serveri viga |
API URL on kõvasti kodeeritud localhost-iks | Kasuta suhtelisi teid või keskkonnapõhist seadet |
CORS Mythexis
Kui Mythexi projektil on veebisait ja API-server, töötavad mõlemad teenustena samas projektis ning eelvaates saad nende vahel vahetada. Kui palud agendil lasta esikülje kutsuda tagakülge läbi suhtelise /api tee, mida arenduses proxy'takse, väldid enamikku CORS-probleeme. Kui vajad päritolude vahelisi kutseid, anna agendile täpne konsooliviga ja asjassepuutuvad päritolud. Kontrolli tulemust ka avaldatud äpis, sest selle aadress erineb eelvaatest. Vaata dokumentatsioonist Multi-service apps ja API backends ning meie juhendeid AI-ehitatud äpi silumisest ja esikülg vs tagakülg.
CORS kontrollnimekiri
- Loetud kogu konsooliviga ja ebaõnnestunud päringu staatusekood
- Välistatud peidetud 404 või 500
- Salajase võtmega API-d kutsutakse tagakülje, mitte brauseri kaudu
- Server saadab
Access-Control-Allow-Origintäpsete lubatud päritoludega -
OPTIONSpreflight vastatakse lubatud meetodite ja päistega, enne autentimist - CORS-päised on olemas ka veavastustel
- Mandaadid: täpne päritolu,
Allow-Credentials: true, õiged küpsiste seaded - Eelvaate, avaldatud ja kohandatud domeeni päritolud kõik kaetud või kasutatud suhtelisi
/apiteid - Ei kasutata
no-cors-i, avalikke proxy'sid ega suvalise päritolu peegeldamise otseteid
Küsimused
Mida tähendab CORS-viga?
Su leht, mis laaditi ühelt päritolult, proovis lugeda vastust teiselt päritolult, ja selle serveri vastus ei sisaldanud päiseid, mis seda lubavad. Brauser blokeerib su koodi vastuse lugemise. Parandus tuleb serverist või sellest, kuidas päring marsruudistatakse, mitte esikülje koodist.
Kas CORS-vea saab parandada esikülje poolt?
Mitte korralikult. Sellised seaded nagu mode: 'no-cors' ainult peidavad vastuse su koodi eest. Parandad selle, kui laseb serveril saata õige Access-Control-Allow-Origin päise või kutsud API-d oma tagakülje või sama päritolu proxy kaudu.
Kas Access-Control-Allow-Origin: * on ohutu?
See sobib avalikele andmetele, mida võib lugeda igaüks, näiteks avalikule API-le ilma sisselogimiseta. Seda ei saa kasutada küpsiste ega muude mandaatidega, ja privaatsete API-de puhul peaksid loetlema täpsed lubatud päritolud.
Miks minu päring töötab Postmanis või curl'is, aga mitte brauseris?
CORS-i jõustavad ainult brauserid. Sellised tööriistad nagu Postman ja curl seda ei rakenda, seega päring võib seal õnnestuda ja ikka blokeeritakse, kui lehe JavaScript selle teeb.
Mis on preflight-päring?
Mitte-lihtsate päringute, nagu JSON POST või päring Authorization päisega, puhul saadab brauser enne esmalt OPTIONS-päringu, et küsida serverilt, milliseid meetodeid ja päiseid lubatakse. Kui see OPTIONS-päring ebaõnnestub või puuduvad õiged päised, ei saadeta tegelikku päringut kunagi.