Guides

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:

URLOrigin
https://myapp.com/dashboardhttps://myapp.com
https://api.myapp.com/usershttps://api.myapp.com (anden subdomæne, så en anden origin)
http://localhost:5173http://localhost:5173
http://localhost:3000http://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 indeholderHvad der er galt
No 'Access-Control-Allow-Origin' header is presentServeren 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 originServeren tillader en anden origin end din
Response to preflight request doesn't pass access control checkOPTIONS-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 allowedServeren 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.com
  • Access-Control-Allow-Methods: GET, POST, PUT, PATCH, DELETE
  • Access-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.com kalder API'et på https://api.myapp.com og får "Response to preflight request doesn't pass access control check". Konfigurér CORS på API'et, så det tillader præcis https://myapp.com og 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, eller withCredentials: true i axios.
  • Serveren sender Access-Control-Allow-Credentials: true.
  • Serverens Access-Control-Allow-Origin skal 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 /api til din backend på en anden port, så browseren kun taler med én origin.
  • I produktion routes /api til 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" i fetch. 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

SituationRettelse
Frontend kalder et tredjeparts-API med en hemmelig nøgleFlyt kaldet til backend
Virker i preview, fejler på det publicerede domæneTilføj de publicerede og egne domæners origins til allowlisten, eller brug relative /api-stier
Fejl kun på POST, PUT eller DELETEPreflight ikke håndteret; tilføj OPTIONS-håndtering og tilladte headere
Fejl opstod efter tilføjelse af loginCredentials kræver en præcis origin og Allow-Credentials
"CORS-fejl", men Network-fanen viser 500Ret serverfejlen først
API-URL hardcoded til localhostBrug 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-Origin med 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: true og 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.

Mythex · Pricing · Byg hvad som helst med AI · Skabeloner til websites og apps · Mythex sammenlignet · Ordliste for app-bygning med AI · Gratis værktøjer til app-bygning med AI · English

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