Slik fikser du CORS-feil (og hvorfor de oppstår)
En CORS-feil betyr at nettsiden din prøvde å lese et svar fra en annen opprinnelse (et annet domene, port eller protokoll), og at den serveren ikke sendte headere som sier at det er tillatt. Nettlesere blokkerer svaret for å beskytte brukerne. Du fikser det på serveren, ved å returnere en Access-Control-Allow-Origin-header for nettstedets opprinnelse og håndtere OPTIONS-preflight-forespørsler, eller du unngår det ved å sende forespørselen gjennom din egen backend på samme opprinnelse.
Det er en av de mest forvirrende feilene i webutvikling, fordi forespørselen ofte når serveren greit. Denne guiden forklarer hva som skjer og hvordan du fikser hver variant.
Hva «opprinnelse» betyr
En opprinnelse (origin) er kombinasjonen av protokoll, domene og port:
| URL | Opprinnelse |
|---|---|
https://minapp.no/dashboard | https://minapp.no |
https://api.minapp.no/users | https://api.minapp.no (annet subdomene, altså annen opprinnelse) |
http://localhost:5173 | http://localhost:5173 |
http://localhost:3000 | http://localhost:3000 (annen port, altså annen opprinnelse) |
Nettlesere følger same-origin-policyen: JavaScript på en side kan lese svar fra sin egen opprinnelse fritt, men ikke fra andre. CORS (Cross-Origin Resource Sharing) er systemet som lar en server si ja: «svar fra meg kan leses av sider fra disse opprinnelsene.»
To konsekvenser overrasker folk:
- Forespørselen når ofte serveren. CORS hindrer vanligvis koden din i å lese svaret, ikke serveren i å motta forespørselen. Et POST kan ha blitt lagret, selv om du så en feil.
- Bare nettlesere håndhever det. curl, Postman og kode på serversiden ignorerer CORS helt. Derfor betyr «det fungerer i Postman» ingenting for CORS.
Steg 1: Les den nøyaktige feilen
Åpne utviklerverktøyene (høyreklikk → Inspiser), gå til Konsoll, og les hele meldingen. Chromes formulering forteller deg hvilket problem du har:
| Meldingen inneholder | Hva som er galt |
|---|---|
No 'Access-Control-Allow-Origin' header is present | Serveren sendte ikke headeren i det hele tatt, eller forespørselen feilet før den nådde CORS-koden din (for eksempel en 404 eller 500) |
The 'Access-Control-Allow-Origin' header has a value '...' that is not equal to the supplied origin | Serveren tillater en annen opprinnelse enn din |
Response to preflight request doesn't pass access control check | OPTIONS-preflight feilet |
...must not be the wildcard '*' when the request's credentials mode is 'include' | Du sender informasjonskapsler, og serveren svarte med * |
Request header field authorization is not allowed | Serveren listet ikke den headeren i Access-Control-Allow-Headers |
Åpne deretter fanen Nettverk, finn den mislykkede forespørselen (og eventuelle OPTIONS-forespørsler før den), og se på statuskoden og svar-headerne.
Sjekk statuskoden først. Mange «CORS-feil» er egentlig en serverfeil i forkledning. Hvis serveren krasjer eller returnerer 404, mangler feilsvaret ofte CORS-headere, så nettleseren rapporterer CORS i stedet for det egentlige problemet. Fiks 500- eller 404-feilen, så kan CORS-feilen forsvinne.
Steg 2: Avgjør om du i det hele tatt bør kalle det API-et fra nettleseren
Før du legger til headere, spør: bør nettleseren i det hele tatt kalle dette API-et direkte?
- Et tredjeparts-API som krever en hemmelig nøkkel (OpenAI, Stripe-hemmelig nøkkel, de fleste e-posttjenester) skal aldri kalles fra nettleseren. Nøkkelen ville vært synlig for alle besøkende. Kall det fra backenden din i stedet, så forsvinner CORS-problemet, fordi forespørsler mellom servere ikke er underlagt CORS. Se hvordan du holder API-nøkler trygge.
- Et tredjeparts-API du ikke kontrollerer som ikke sender CORS-headere, kan ikke fikses fra din side. Kall det fra backenden din.
- Ditt eget API kan fikses ved å konfigurere det riktig. Fortsett under.
Steg 3: Fiks det på serveren din
Serveren må legge til de riktige headerne i svarene sine, også i feilsvar.
For den faktiske forespørselen sender du:
Access-Control-Allow-Origin: https://minapp.no(den nøyaktige opprinnelsen til frontenden din, uten skråstrek på slutten)Vary: Origin, hvis verdien avhenger av hvilken opprinnelse som spurte
For den mellomliggende OPTIONS-forespørselen (preflight) svarer du med en vellykket status (200 eller 204) og:
Access-Control-Allow-Origin: https://minapp.noAccess-Control-Allow-Methods: GET, POST, PUT, PATCH, DELETEAccess-Control-Allow-Headers: Content-Type, Authorization(hver egen header du sender)- Valgfritt
Access-Control-Max-Age: 600, slik at nettleseren cacher preflight en stund
De fleste rammeverk har en pakke eller innstilling som gjør dette. I Express er det pakken cors; i FastAPI er det CORSMiddleware; i ASP.NET Core er det AddCors; i Spring er det @CrossOrigin eller en CORS-konfigurasjon. Et typisk Express-oppsett:
import cors from "cors";
app.use(cors({
origin: ["https://minapp.no", "http://localhost:5173"],
credentials: true,
}));
Legg CORS-håndteringen før rutene og autentiseringen din, slik at preflight-forespørsler (som ikke bærer innlogging) ikke avvises med 401.
Med en AI-bygger beskriver du oppsettet presist:
Frontenden på
https://minapp.nokaller API-et påhttps://api.minapp.noog får «Response to preflight request doesn't pass access control check». Konfigurer CORS på API-et til å tillate nøyaktighttps://minapp.noog forhåndsvisningens opprinnelse, tillat GET, POST, PATCH, DELETE med headerne Content-Type og Authorization, håndter OPTIONS før autentisering, og ta med CORS-headere også på feilsvar.
Steg 4: Håndter informasjonskapsler og legitimasjon
Hvis frontenden din sender informasjonskapsler (for eksempel en innloggingssesjon) til en annen opprinnelse, må begge sider være enige:
- Frontenden setter
credentials: "include"påfetch, ellerwithCredentials: truei axios. - Serveren sender
Access-Control-Allow-Credentials: true. - Serverens
Access-Control-Allow-Originmå være den nøyaktige opprinnelsen, ikke*.
Informasjonskapsler på tvers av sider trenger også SameSite=None; Secure på kapselen, og noen nettlesere begrenser tredjeparts-informasjonskapsler ytterligere. Det er én grunn til å foretrekke tilnærmingen i steg 5.
Steg 5: Unngå CORS med et oppsett med samme opprinnelse
Ofte er den reneste løsningen å ikke gjøre forespørsler på tvers av opprinnelser i det hele tatt. Server API-et fra samme opprinnelse som siden, for eksempel på https://minapp.no/api/...:
- I utvikling kan de fleste utviklingsservere lage en proxy. Vites
server.proxy-innstilling kan videresende/apitil backenden din på en annen port, slik at nettleseren bare snakker med én opprinnelse. - I produksjon ruter du
/apitil backenden via hostens rewrite- eller proxy-innstillinger, eller serverer frontend og API fra én server.
Frontenden kaller da en relativ sti som fetch("/api/orders"). Det finnes ingen forespørsel på tvers av opprinnelser, ingen preflight mellom opprinnelser og ingen problemer med informasjonskapsler. Det betyr også at du ikke hardkoder et API-domene som er forskjellig mellom forhåndsvisning og produksjon.
Endre frontenden til å kalle backenden med relative /api-stier i stedet for en full URL, og sett opp en dev-proxy slik at /api videresendes til API-serveren. Fjern deretter CORS-innstillinger vi ikke lenger trenger.
Hva du ikke bør gjøre
mode: "no-cors"ifetch. Det omgår ingenting; det gir koden din et tomt, uleselig svar.- Nettleserutvidelser som slår av CORS. De endrer bare nettleseren din. Alle besøkende ser fortsatt feilen.
- Offentlige «CORS-proxy»-tjenester for ekte apper. De kan lese og endre alt som passerer gjennom dem, og de går ned.
Access-Control-Allow-Origin: *på et API som bruker innlogging. Det fungerer ikke med legitimasjon uansett, og det er feil standard for private data.- Å speile tilbake enhver
Origin-header med innlogging tillatt. Det lar et hvilket som helst nettsted gjøre innloggede forespørsler på vegne av brukerne dine. Bruk en tillatelsesliste.
Vanlige årsaker i AI-bygde apper
| Situasjon | Løsning |
|---|---|
| Frontenden kaller et tredjeparts-API med en hemmelig nøkkel | Flytt kallet til backenden |
| Fungerer i forhåndsvisningen, men feiler på det publiserte domenet | Legg til det publiserte domenet og egendomenet i tillatelseslisten, eller bruk relative /api-stier |
| Feil bare på POST, PUT eller DELETE | Preflight ikke håndtert; legg til OPTIONS-håndtering og tillatte headere |
| Feilen kom etter at du la til innlogging | Legitimasjon krever nøyaktig opprinnelse og Allow-Credentials |
| «CORS-feil», men fanen Nettverk viser 500 | Fiks serverfeilen først |
API-URL hardkodet til localhost | Bruk relative stier eller en innstilling per miljø |
CORS i Mythex
Når et Mythex-prosjekt har et nettsted og en API-server, kjører begge som tjenester i samme prosjekt, og du kan bytte mellom dem i forhåndsvisningen. Hvis du ber agenten om at frontenden kaller backenden via en relativ /api-sti, proxyet i utvikling, unngår du de fleste CORS-problemer. Hvis du likevel trenger kall på tvers av opprinnelser, gi agenten den nøyaktige feilen fra konsollen og opprinnelsene som er involvert. Sjekk resultatet også på den publiserte appen, siden adressen er en annen enn i forhåndsvisningen. Se Flertjeneste-apper og API-backender i dokumentasjonen, og våre guider om feilsøking av en AI-bygd app og frontend kontra backend.
Sjekkliste for CORS
- Leste hele konsollfeilen og statuskoden for den mislykkede forespørselen
- Utelukket en skjult 404 eller 500
- API-er med hemmelige nøkler kalles fra backenden, ikke nettleseren
- Serveren sender
Access-Control-Allow-Originmed de nøyaktige tillatte opprinnelsene -
OPTIONS-preflight besvares med tillatte metoder og headere, før autentisering - CORS-headere finnes også på feilsvar
- Legitimasjon: nøyaktig opprinnelse,
Allow-Credentials: trueog riktige informasjonskapsel-innstillinger - Forhåndsvisning, publisert domene og egendomene er dekket, eller relative
/api-stier brukes - Ingen
no-cors, offentlige proxyer eller speiling av vilkårlige opprinnelser
Spørsmål
Hva betyr en CORS-feil?
Siden din, lastet fra én opprinnelse, prøvde å lese et svar fra en annen opprinnelse, og den serverens svar hadde ikke headere som tillot det. Nettleseren blokkerer koden din fra å lese svaret. Løsningen ligger på serveren, eller i hvordan forespørselen rutes, ikke i frontend-koden.
Kan jeg fikse en CORS-feil fra frontend?
Ikke skikkelig. Innstillinger som mode: 'no-cors' skjuler bare svaret for koden din. Du fikser det ved å la serveren sende riktig Access-Control-Allow-Origin-header, eller ved å kalle API-et fra din egen backend eller en proxy med samme opprinnelse.
Er Access-Control-Allow-Origin: * trygt?
Det er greit for offentlige data som alle kan lese, for eksempel et offentlig API uten innlogging. Det kan ikke brukes sammen med informasjonskapsler eller andre legitimasjoner, og for private API-er bør du liste de nøyaktige tillatte opprinnelsene.
Hvorfor fungerer forespørselen i Postman eller curl, men ikke i nettleseren?
CORS håndheves bare av nettlesere. Verktøy som Postman og curl bruker det ikke, så en forespørsel kan lykkes der og likevel blokkeres når JavaScript på siden sender den.
Hva er en preflight-forespørsel?
For forespørsler som ikke er enkle, for eksempel en JSON-POST eller en med en Authorization-header, sender nettleseren først en OPTIONS-forespørsel for å spørre serveren hvilke metoder og headere som tillates. Hvis OPTIONS-forespørselen feiler eller mangler de riktige headerne, sendes aldri den egentlige forespørselen.