Sådan retter du CORS-fejl (og hvorfor de opstår)
En CORS-fejl betyder, at din webside forsøgte at læse et svar fra en anden origin (et andet domæne, port eller protokol), og at den server ikke sendte headere, der siger, at det er tilladt. Browsere blokerer svaret for at beskytte brugerne. Du retter det på serveren ved at returnere en Access-Control-Allow-Origin-header for dit sites origin og håndtere OPTIONS preflight-forespørgsler, eller du undgår det ved at sende forespørgslen gennem din egen backend på samme origin.
Det er en af de mest forvirrende fejl i webudvikling, fordi forespørgslen ofte når serveren fint. Denne guide forklarer, hvad der sker, og hvordan du retter hver variant.
Hvad "origin" betyder
En origin er kombinationen af protokol, domæne og port:
| URL | Origin |
|---|---|
https://myapp.com/dashboard | https://myapp.com |
https://api.myapp.com/users | https://api.myapp.com (anden subdomæne, så en anden origin) |
http://localhost:5173 | http://localhost:5173 |
http://localhost:3000 | http://localhost:3000 (anden port, så en anden origin) |
Browsere følger same-origin-politikken: JavaScript på en side kan frit læse svar fra sin egen origin, men ikke fra andre. CORS (Cross-Origin Resource Sharing) er systemet, der lader en server give samtykke: "svar fra mig må læses af sider fra disse origins."
To konsekvenser overrasker folk:
- Forespørgslen når ofte serveren. CORS forhindrer normalt din kode i at læse svaret, ikke serveren i at modtage forespørgslen. Et POST kan være gemt, selvom du så en fejl.
- Kun browsere håndhæver det. curl, Postman og server-side kode ignorerer CORS helt. Derfor siger "det virker i Postman" intet om CORS.
Trin 1: Læs den præcise fejl
Åbn udviklerværktøjerne (højreklik → Inspicér), gå til Console, og læs hele beskeden. Chromes formulering fortæller dig, hvilket problem du har:
| Beskeden indeholder | Hvad der er galt |
|---|---|
No 'Access-Control-Allow-Origin' header is present | Serveren sendte slet ikke headeren, eller forespørgslen fejlede, før den nåede din CORS-kode (f.eks. en 404 eller 500) |
The 'Access-Control-Allow-Origin' header has a value '...' that is not equal to the supplied origin | Serveren tillader en anden origin end din |
Response to preflight request doesn't pass access control check | OPTIONS-preflight'en fejlede |
...must not be the wildcard '*' when the request's credentials mode is 'include' | Du sender cookies, og serveren svarede med * |
Request header field authorization is not allowed | Serveren har ikke angivet headeren i Access-Control-Allow-Headers |
Åbn derefter fanen Network, find den fejlende forespørgsel (og eventuelle OPTIONS-forespørgsler før den), og se på dens statuskode og svar-headere.
Tjek statuskoden først. Mange "CORS-fejl" er egentlig en serverfejl i forklædning. Hvis serveren crasher eller returnerer en 404, mangler dens fejlsvar ofte CORS-headere, så browseren rapporterer CORS i stedet for det rigtige problem. Ret 500'eren eller 404'eren, og CORS-fejlen kan forsvinde.
Trin 2: Afgør om du overhovedet skal kalde API'et fra browseren
Før du tilføjer headere, spørg: skal browseren overhovedet kalde dette API direkte?
- Et tredjeparts-API, der kræver en hemmelig nøgle (OpenAI, Stripe secret key, de fleste e-mail-tjenester) bør aldrig kaldes fra browseren. Nøglen ville være synlig for alle besøgende. Kald det fra din backend i stedet, og CORS-problemet forsvinder, fordi server-til-server-forespørgsler ikke er underlagt CORS. Se sådan holder du API-nøgler sikre.
- Et tredjeparts-API, du ikke kontrollerer, som ikke sender CORS-headere, kan ikke rettes fra din side. Kald det fra din backend.
- Dit eget API kan rettes ved at konfigurere det korrekt. Fortsæt nedenfor.
Trin 3: Ret det på din server
Serveren skal tilføje de rigtige headere til sine svar, inklusive fejlsvar.
For den egentlige forespørgsel skal den sende:
Access-Control-Allow-Origin: https://myapp.com(din frontends præcise origin, uden afsluttende skråstreg)Vary: Origin, hvis værdien afhænger af, hvilken origin der spurgte
For den præflight OPTIONS-forespørgsel skal den svare med en successtatus (200 eller 204) og:
Access-Control-Allow-Origin: https://myapp.comAccess-Control-Allow-Methods: GET, POST, PUT, PATCH, DELETEAccess-Control-Allow-Headers: Content-Type, Authorization(hver custom header du sender)- Valgfrit
Access-Control-Max-Age: 600, så browseren cacher preflight'en en tid
De fleste frameworks har en pakke eller indstilling, der gø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-konfiguration. En typisk Express-opsætning:
import cors from "cors";
app.use(cors({
origin: ["https://myapp.com", "http://localhost:5173"],
credentials: true,
}));
Placér CORS-håndtering før dine ruter og din autentificering, så preflight-forespørgsler (som ikke bærer et login) ikke afvises med en 401.
Med en AI-builder, beskriv opsætningen præcist:
Frontend'en på
https://myapp.comkalder API'et påhttps://api.myapp.comog får "Response to preflight request doesn't pass access control check". Konfigurér CORS på API'et, så det tillader præcishttps://myapp.comog preview-originen, tillad GET, POST, PATCH, DELETE med Content-Type- og Authorization-headere, håndtér OPTIONS før autentificering, og inkludér også CORS-headere på fejlsvar.
Trin 4: Håndtér cookies og credentials
Hvis din frontend sender cookies (f.eks. en login-session) til en anden origin, skal begge sider være enige:
- Frontend sætter
credentials: "include"påfetch, ellerwithCredentials: truei axios. - Serveren sender
Access-Control-Allow-Credentials: true. - Serverens
Access-Control-Allow-Originskal være den præcise origin, ikke*.
Cookies på tværs af sites kræver også SameSite=None; Secure på cookien, og nogle browsere begrænser tredjepartscookies yderligere. Det er endnu en grund til at foretrække tilgangen i Trin 5.
Trin 5: Undgå CORS med en same-origin-opsætning
Den reneste rettelse er ofte slet ikke at lave cross-origin-forespørgsler. Server API'et fra samme origin som siden, for eksempel på https://myapp.com/api/...:
- I udvikling kan de fleste dev-servere proxy'e. Vites
server.proxy-indstilling kan videresende/apitil din backend på en anden port, så browseren kun taler med én origin. - I produktion routes
/apitil backend via din hosts rewrite- eller proxy-indstillinger, eller du serverer frontend og API fra én server.
Frontend'en kalder så en relativ sti som fetch("/api/orders"). Der er ingen cross-origin-forespørgsel, ingen preflight på tværs af origins og ingen cookie-hovedpine. Det betyder også, at du ikke hardcoder et API-domæne, der er forskelligt mellem preview og produktion.
Ændr frontend'en til at kalde backend med relative /api-stier i stedet for en fuld URL, og opsæt en dev-proxy, så /api videresendes til API-serveren. Fjern derefter eventuelle CORS-indstillinger, vi ikke længere har brug for.
Hvad du ikke skal gøre
mode: "no-cors"ifetch. Det omgår intet; det giver din kode et tomt, ulæseligt svar.- Browserudvidelser, der deaktiverer CORS. De ændrer kun din browser. Alle besøgende ser stadig fejlen.
- Offentlige "CORS-proxy"-tjenester til rigtige apps. De kan læse og ændre alt, der går igennem dem, og de går ned.
Access-Control-Allow-Origin: *på et API, der bruger logins. Det virker ikke med credentials alligevel, og det er den forkerte standard for private data.- At spejle enhver
Origin-header tilbage, når credentials er tilladt. Det lader ethvert website lave forespørgsler med login på dine brugeres vegne. Brug en allowlist.
Almindelige årsager i AI-byggede apps
| Situation | Rettelse |
|---|---|
| Frontend kalder et tredjeparts-API med en hemmelig nøgle | Flyt kaldet til backend |
| Virker i preview, fejler på det publicerede domæne | Tilføj de publicerede og egne domæners origins til allowlisten, eller brug relative /api-stier |
| Fejl kun på POST, PUT eller DELETE | Preflight ikke håndteret; tilføj OPTIONS-håndtering og tilladte headere |
| Fejl opstod efter tilføjelse af login | Credentials kræver en præcis origin og Allow-Credentials |
| "CORS-fejl", men Network-fanen viser 500 | Ret serverfejlen først |
API-URL hardcoded til localhost | Brug relative stier eller en indstilling pr. miljø |
CORS i Mythex
Når et Mythex-projekt har et website og en API-server, kører begge som tjenester i samme projekt, og du kan skifte mellem dem i preview. At bede agenten om at få frontend til at kalde backend gennem en relativ /api-sti, proxied i udvikling, undgår de fleste CORS-problemer. Hvis du faktisk har brug for cross-origin-kald, så giv agenten den præcise fejl fra konsollen og de involverede origins. Tjek resultatet også på den publicerede app, da dens adresse er en anden end preview'ets. Se Multi-service apps og API-backends i dokumentationen, og vores guides om fejlfinding af en AI-bygget app og frontend vs. backend.
CORS-tjekliste
- Læst hele konsolfejlen og den fejlende forespørgsels statuskode
- Udelukket en skjult 404 eller 500
- API'er med hemmelige nøgler kaldes fra backend, ikke browseren
- Serveren sender
Access-Control-Allow-Originmed præcise tilladte origins -
OPTIONS-preflight besvaret med tilladte metoder og headere, før autentificering - CORS-headere til stede på fejlsvar
- Credentials: præcis origin,
Allow-Credentials: trueog korrekte cookie-indstillinger - Preview-, publicerede og egne domæners origins dækket, eller relative
/api-stier brugt - Ingen
no-cors, offentlige proxies eller spejl-enhver-origin-genveje
Spørgsmål
Hvad betyder en CORS-fejl?
Din side, indlæst fra én origin, forsøgte at læse et svar fra en anden origin, og den serverens svar indeholdt ikke headere, der tillod det. Browseren forhindrer din kode i at læse svaret. Rettelsen ligger på serveren, eller i hvordan forespørgslen routes, ikke i front end-koden.
Kan jeg rette en CORS-fejl fra frontend?
Ikke ordentligt. Indstillinger som mode: 'no-cors' skjuler kun svaret for din kode. Du retter det ved at få serveren til at sende den rigtige Access-Control-Allow-Origin-header, eller ved at kalde API'et fra din egen backend eller en same-origin-proxy.
Er Access-Control-Allow-Origin: * sikkert?
Det er fint for offentlige data, som alle må læse, f.eks. et offentligt API uden login. Det kan ikke bruges sammen med cookies eller andre credentials, og for private API'er bør du angive de præcise origins, der må få adgang.
Hvorfor virker en forespørgsel i Postman eller curl, men ikke i browseren?
CORS håndhæves kun af browsere. Værktøjer som Postman og curl anvender det ikke, så en forespørgsel kan lykkes dér og stadig blive blokeret, når sidens JavaScript sender den.
Hvad er en preflight-forespørgsel?
For forespørgsler, der ikke er simple, som en JSON POST eller en med en Authorization-header, sender browseren først en OPTIONS-forespørgsel for at spørge serveren, hvilke metoder og headere der er tilladt. Hvis den OPTIONS-forespørgsel fejler eller mangler de rigtige headere, sendes den egentlige forespørgsel aldrig.