Oppaat

Näin korjaat CORS-virheet ja ymmärrät, miksi ne syntyvät

CORS-virhe tarkoittaa, että web-sivusi yritti lukea vastauksen toisesta originista (toisesta domainista, portista tai protokollasta), eikä sen palvelin lähettänyt otsikoita, jotka sallivat sen. Selaimet estävät vastauksen suojellakseen käyttäjiä. Korjaat sen palvelimella: palautat sivustosi originille Access-Control-Allow-Origin-otsikon ja käsittelet OPTIONS-esilento-pyynnöt. Tai vältät virheen lähettämällä pyynnön oman takapäsi kautta samassa originissa.

Se on yksi web-kehityksen sekavimmista virheistä, koska pyyntö usein saavuttaa palvelimen hyvin. Tämä opas selittää, mitä tapahtuu, ja miten korjata kukin variantti.

Mitä ”origin” tarkoittaa

Origin on protokollan, domainin ja portin yhdistelmä:

URLOrigin
https://omasovellus.fi/dashboardhttps://omasovellus.fi
https://api.omasovellus.fi/usershttps://api.omasovellus.fi (eri aliaksen vuoksi eri origin)
http://localhost:5173http://localhost:5173
http://localhost:3000http://localhost:3000 (eri portin vuoksi eri origin)

Selaimet noudattavat samaa originia koskevaa käytäntöä: sivun JavaScript voi vapaasti lukea oman originsa vastaukset, mutta ei muiden. CORS (Cross-Origin Resource Sharing) on järjestelmä, jolla palvelin voi antaa luvan: ”sivut näistä origineista saavat lukea vastaukseni”.

Kaksi seikkaa yllättää ihmisiä:

  • Pyyntö usein saavuttaa palvelimen. CORS estää yleensä koodiasi lukemasta vastausta, ei palvelinta vastaanottamasta pyyntöä. POST on saattanut tallentua, vaikka näit virheen.
  • Vain selaimet noudattavat sitä. curl, Postman ja palvelinpuolen koodi eivät välitä CORS:sta lainkaan. Siksi ”toimii Postmanissa” ei kerro sinulle mitään CORS:sta.

Vaihe 1: Lue tarkka virhe

Avaa kehittäjätyökalut (oikea klikkaus → Tarkista), siirry Console-välilehdelle ja lue koko viesti. Chromen sanamuoto kertoo, mikä ongelma on:

Viesti sisältääMikä on vialla
No 'Access-Control-Allow-Origin' header is presentPalvelin ei lähettänyt otsikkoa lainkaan, tai pyyntö epäonnistui ennen CORS-koodiasi (esimerkiksi 404 tai 500)
The 'Access-Control-Allow-Origin' header has a value '...' that is not equal to the supplied originPalvelin sallii jonkin muun originin kuin sinun
Response to preflight request doesn't pass access control checkOPTIONS-esilento epäonnistui
...must not be the wildcard '*' when the request's credentials mode is 'include'Lähetät evästeitä, ja palvelin vastasi *-merkillä
Request header field authorization is not allowedPalvelin ei listannut tätä otsikkoa kohdassa Access-Control-Allow-Headers

Avaa sen jälkeen Network-välilehti, etsi epäonnistunut pyyntö (ja mahdollinen sitä edeltävä OPTIONS-pyyntö) ja katso sen tilakoodi ja vastausotsikot.

Tarkista ensin tilakoodi. Monet ”CORS-virheet” ovat oikeasti palvelinvirheitä naamioituneina. Jos palvelin kaatuu tai palauttaa 404:n, sen virhevastauksesta puuttuvat usein CORS-otsikot, joten selain raportoi CORS-virheen oikean ongelman sijaan. Korjaa 500 tai 404 ensin, ja CORS-virhe voi kadota.

Vaihe 2: Päätä, pitäisikö selaimen kutsua tätä API:a ollenkaan

Ennen kuin lisäät otsikoita, kysy: pitäisikö selaimen kutsua tätä API:a suoraan?

  • Kolmannen osapuolen API, joka vaatii salaisen avaimen (OpenAI, Stripen salainen avain, useimmat sähköpostipalvelut), ei koskaan pidä kutsua selaimesta. Avain näkyisi jokaiselle kävijälle. Kutsu se takapäästäsi, ja CORS-ongelma katoaa, koska palvelin-palvelin-pyynnöt eivät ole CORS:n alaisia. Katso näin pidät API-avaimet turvassa.
  • Kolmannen osapuolen API, jota et hallitse eikä lähetä CORS-otsikoita, ei voi korjata omalta puoleltasi. Kutsu sitä takapäästäsi.
  • Oma API voidaan korjata kunnolla asettamalla se. Jatka alla.

Vaihe 3: Korjaa palvelimellasi

Palvelimen pitää lisätä oikeat otsikot vastauksiinsa, myös virhevastauksiin.

Varsinaiselle pyynnölle lähetä:

  • Access-Control-Allow-Origin: https://omasovellus.fi (frontendisi tarkka origin, ilman perässä olevaa kauttaviivaa)
  • Vary: Origin, jos arvo riippuu siitä, mikä origin pyysi

Esilento-pyynnölle OPTIONS vastaa onnistumistilalla (200 tai 204) ja:

  • Access-Control-Allow-Origin: https://omasovellus.fi
  • Access-Control-Allow-Methods: GET, POST, PUT, PATCH, DELETE
  • Access-Control-Allow-Headers: Content-Type, Authorization (jokainen mukautettu otsikko, jonka lähetät)
  • Valinnaisesti Access-Control-Max-Age: 600, jotta selain välimuistittaa esilennon hetkeksi

Useimmilla kehyksillä on paketti tai asetus, joka tekee tämän. Expressissä cors-paketti; FastAPI:ssa CORSMiddleware; ASP.NET Coressa AddCors; Springissä @CrossOrigin tai CORS-konfiguraatio. Tyypillinen Express-asetus:

import cors from "cors";

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

Sijoita CORS-käsittely ennen reittejäsi ja tunnistautumista, jotta esilento-pyyntöjä (joissa ei ole kirjautumista) ei hylätä 401:llä.

Tekoälyrakentajalla kuvaile asetus tarkasti:

Frontend osoitteessa https://omasovellus.fi kutsuu API:a osoitteessa https://api.omasovellus.fi ja saa virheen ”Response to preflight request doesn't pass access control check”. Määritä API:n CORS sallimaan täsmälleen https://omasovellus.fi ja esikatselun origin, sallia GET, POST, PATCH ja DELETE Content-Type- ja Authorization-otsikoilla, käsitellä OPTIONS ennen tunnistautumista ja sisällyttää CORS-otsikot myös virhevastauksiin.

Vaihe 4: Käsittele evästeet ja tunnistetiedot

Jos frontendisi lähettää evästeitä (esimerkiksi kirjautumisistuntoa) toiseen originiin, molempien osapuolten on oltava samaa mieltä:

  • Frontend asettaa credentials: "include" fetch-kutsuun tai withCredentials: true axiosissa.
  • Palvelin lähettää Access-Control-Allow-Credentials: true.
  • Palvelimen Access-Control-Allow-Origin on oltava tarkka origin, ei *.

Evästeet eri sivustojen välillä tarvitsevat myös SameSite=None; Secure-asetuksen, ja jotkut selaimet rajoittavat kolmannen osapuolen evästeitä vielä enemmän. Se on yksi lisäsyy suosia Vaiheen 5 lähestymistapaa.

Vaihe 5: Vältä CORS samalla originilla

Usein puhtain korjaus on olla tekemättä domainien välisiä pyyntöjä lainkaan. Tarjoa API samasta originista kuin sivu, esimerkiksi osoitteessa https://omasovellus.fi/api/...:

  • Kehityksessä useimmat kehityspalvelimet voivat välittää pyyntöjä. Viten server.proxy-asetus voi ohjata /api takapäähän toisessa portissa, jolloin selain puhuu aina vain yhdelle originille.
  • Tuotannossa reititä /api takapäähän hostin rewrite- tai proxy-asetuksilla, tai tarjoa frontend ja API yhdeltä palvelimelta.

Frontend kutsuu sitten suhteellista polkua kuten fetch("/api/orders"). Ei domainien välistä pyyntöä, ei originien välistä esilentoa eikä evästeongelmia. Se tarkoittaa myös, ettei API-domainia tarvitse kovakoodata, ja se eroaa esikatselun ja tuotannon välillä.

Muuta frontend kutsumaan takapäätä suhteellisilla /api-poluilla täydellisen URL-osoitteen sijaan, ja aseta kehityksen välityspalvelin ohjaamaan /api API-palvelimelle. Poista sen jälkeen CORS-asetukset, joita emme enää tarvitse.

Mitä ei kannata tehdä

  • mode: "no-cors" fetch-kutsussa. Se ei ohita mitään; se antaa koodillesi tyhjän, lukukelvottoman vastauksen.
  • Selainlaajennukset, jotka poistavat CORSin käytöstä. Ne muuttavat vain omaa selaintasi. Jokainen kävijä näkee yhä virheen.
  • Julkiset ”CORS-välityspalvelut” oikeille sovelluksille. Ne voivat lukea ja muuttaa kaikkea niiden kautta kulkevaa, ja ne menevät välillä alas.
  • Access-Control-Allow-Origin: * API:ssa, joka käyttää kirjautumista. Se ei toimi tunnistetietojen kanssa, ja se on väärä oletus yksityiselle datalle.
  • Minkä tahansa Origin-otsikon heijastaminen takaisin tunnistetietojen sallimisen kanssa. Se antaa minkä tahansa web-sivun tehdä kirjautuneita pyyntöjä käyttäjiesi puolesta. Käytä sallittujen listaa.

Yleisiä syitä tekoälyllä rakennetuissa sovelluksissa

TilanneKorjaus
Frontend kutsuu kolmannen osapuolen API:a salaisella avaimellaSiirrä kutsu takapäähän
Toimii esikatselussa, epäonnistuu julkaistulla domainillaLisää julkaistu ja oma domain originien listalle, tai käytä suhteellisia /api-polkuja
Virhe vain POST-, PUT- tai DELETE-pyynnöissäEsilentoa ei käsitelty; lisää OPTIONS-käsittely ja sallitut otsikot
Virhe ilmestyi kirjautumisen lisäämisen jälkeenTunnistetiedot vaativat tarkan originin ja Allow-Credentials-asetuksen
”CORS-virhe”, mutta Network-välilehdellä 500Korjaa palvelinvirhe ensin
API-osoite kovakoodattu localhost-osoitteeseenKäytä suhteellisia polkuja tai ympäristökohtaista asetusta

CORS Mythexissä

Kun Mythex-projektissa on sekä verkkosivusto että API-palvelin, molemmat toimivat palveluina samassa projektissa, ja niiden välillä voi vaihtaa esikatselussa. Kun pyydät agenttia tekemään frontendin kutsumaan takapäätä suhteellisen /api-polun kautta, joka välitetään kehityksessä, vältät useimmat CORS-ongelmat. Jos tarvitset todella domainien välisiä kutsuja, anna agentille tarkka virhe konsolista ja kyseiset originit. Tarkista tulos myös julkaistusta sovelluksesta, koska sen osoite on eri kuin esikatselun. Katso Monipalveluiset sovellukset ja API-takapäät dokumentaatiosta sekä oppaamme tekoälyllä rakennetun sovelluksen virheenkorjauksesta ja frontend vs. backend.

CORS-tarkistuslista

  • Luettu koko konsolivirhe ja epäonnistuneen pyynnön tilakoodi
  • Suljettu pois piilossa oleva 404 tai 500
  • Salaisen avaimen API:t kutsutaan takapäästä, ei selaimesta
  • Palvelin lähettää Access-Control-Allow-Origin-otsikon tarkoilla sallituilla originilla
  • OPTIONS-esilento vastataan sallituilla metodeilla ja otsikoilla, ennen tunnistautumista
  • CORS-otsikot ovat mukana myös virhevastauksissa
  • Tunnistetiedot: tarkka origin, Allow-Credentials: true ja oikeat evästeasetukset
  • Esikatselun, julkaistun ja oman domainin originit kaikki katettu tai käytetty suhteellisia /api-polkuja
  • Ei no-cors-asetusta, julkisia välityspalveluja tai kaiken heijastavia originijärjestelyjä

Kysymykset

Mitä CORS-virhe tarkoittaa?

Sivusi, joka latautui yhdestä originista, yritti lukea vastauksen toisesta originista, eikä sen palvelimen vastaus sisältänyt sallivia otsikoita. Selain estää koodiasi lukemasta vastausta. Korjaus tehdään palvelimella tai siinä, miten pyyntö reititetään, ei frontend-koodissa.

Voinko korjata CORS-virheen frontendistä?

Ei kunnolla. Asetukset kuten mode: 'no-cors' vain piilottavat vastauksen koodiltasi. Korjaat sen saamalla palvelimen lähettämään oikean Access-Control-Allow-Origin-otsikon tai kutsumalla API:a omalta takapäältäsi tai saman originin välityspalvelimen kautta.

Onko Access-Control-Allow-Origin: * turvallinen?

Se on sopiva julkiselle datalle, jota kuka tahansa saa lukea, kuten julkiselle API:lle ilman kirjautumista. Sitä ei voi käyttää evästeiden tai muiden tunnistetietojen kanssa, ja yksityisille API:ille sinun kannattaa listata tarkat sallitut originit.

Miksi pyyntö toimii Postmanissa tai curlissa mutta ei selaimessa?

CORS-tarkistus tehdään vain selaimissa. Työkalut kuten Postman ja curl eivät sovella sitä, joten pyyntö voi onnistua siellä ja silti estyä, kun sivun JavaScript tekee sen.

Mikä on esilento-pyyntö (preflight)?

Pyynnöille, jotka eivät ole yksinkertaisia, kuten JSON-POST tai pyyntö, jossa on Authorization-otsikko, selain lähettää ensin OPTIONS-pyynnön ja kysyy palvelimelta, mitkä metodit ja otsikot ovat sallittuja. Jos tuo OPTIONS-pyyntö epäonnistuu tai siitä puuttuvat oikeat otsikot, varsinaista pyyntöä ei lähetetä ollenkaan.

Mythex · Pricing · Rakenna mitä tahansa tekoälyllä · Verkkosivu- ja sovellusmallipohjat · Mythex vertailussa · Tekoälysovellusten rakentamisen sanasto · Ilmaiset työkalut tekoälysovellusten rakentamiseen · English

English አማርኛ العربية Български বাংলা Bosanski Català Čeština Dansk Deutsch Ελληνικά Español Español (España) Eesti فارسی 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 简体中文 繁體中文(香港) 繁體中文(台灣)