Så åtgärdar du CORS-fel (och varför de uppstår)
Ett CORS-fel betyder att din webbsida försökte läsa ett svar från en annan origin (en annan domän, port eller protokoll), och att servern inte skickade headers som säger att det är tillåtet. Webbläsare blockerar svaret för att skydda användarna. Du åtgärdar det på servern, genom att returnera en Access-Control-Allow-Origin-header för din sajts origin och hantera OPTIONS-preflight-begäranden, eller undviker det genom att skicka begäran via din egen backend på samma origin.
Det är ett av de mest förvirrande felen i webbutveckling eftersom begäran ofta når servern utan problem. Den här guiden förklarar vad som händer och hur du åtgärdar varje variant.
Vad ”origin” betyder
En origin är kombinationen av protokoll, domän och port:
| URL | Origin |
|---|---|
https://myapp.com/dashboard | https://myapp.com |
https://api.myapp.com/users | https://api.myapp.com (annan subdomän, alltså annan origin) |
http://localhost:5173 | http://localhost:5173 |
http://localhost:3000 | http://localhost:3000 (annan port, alltså annan origin) |
Webbläsare följer same-origin-policyn: JavaScript på en sida får fritt läsa svar från sin egen origin, men inte från andra. CORS (Cross-Origin Resource Sharing) är systemet som låter en server välja att tillåta det: ”svar från mig får läsas av sidor från dessa origins.”
Två saker överraskar ofta:
- Begäran når ofta servern. CORS blockerar oftast din kod från att läsa svaret, inte servern från att ta emot begäran. Ett POST kan ha sparats även om du såg ett fel.
- Bara webbläsare tillämpar det. curl, Postman och kod på serversidan ignorerar CORS helt. Därför säger ”det fungerar i Postman” ingenting om CORS.
Steg 1: Läs det exakta felet
Öppna utvecklarverktygen (högerklicka → Inspektera), gå till Konsol och läs hela meddelandet. Chromes formulering visar vilket problem du har:
| Meddelandet innehåller | Vad som är fel |
|---|---|
No 'Access-Control-Allow-Origin' header is present | Servern skickade inte headern alls, eller så misslyckades begäran innan den nådde din CORS-kod (till exempel 404 eller 500) |
The 'Access-Control-Allow-Origin' header has a value '...' that is not equal to the supplied origin | Servern tillåter en annan origin än din |
Response to preflight request doesn't pass access control check | OPTIONS-preflighten misslyckades |
...must not be the wildcard '*' when the request's credentials mode is 'include' | Du skickar cookies, och servern svarade med * |
Request header field authorization is not allowed | Servern listade inte den headern i Access-Control-Allow-Headers |
Öppna sedan fliken Nätverk, hitta den misslyckade begäran (och eventuella OPTIONS-begäranden före den) och titta på dess statuskod och svarsheaders.
Kontrollera statuskoden först. Många ”CORS-fel” är egentligen ett serverfel i förklädnad. Om servern kraschar eller returnerar 404 saknar dess felsvar ofta CORS-headers, så webbläsaren rapporterar CORS i stället för det verkliga problemet. Åtgärda 500:an eller 404:an, så kan CORS-felet försvinna.
Steg 2: Avgör om webbläsaren alls ska anropa det API:t
Innan du lägger till headers, fråga dig: ska webbläsaren anropa det här API:t direkt?
- Ett API från en tredje part som kräver en hemlig nyckel (OpenAI, Stripes hemliga nyckel, de flesta e-posttjänster) ska aldrig anropas från webbläsaren. Nyckeln skulle vara synlig för varje besökare. Anropa det från din backend i stället, så försvinner CORS-problemet, eftersom server-till-server-begäranden inte omfattas av CORS. Se så håller du API-nycklar säkra.
- Ett API från en tredje part som du inte kontrollerar och som inte skickar CORS-headers kan inte åtgärdas från din sida. Anropa det från din backend.
- Ditt eget API kan åtgärdas genom att konfigurera det ordentligt. Fortsätt nedan.
Steg 3: Åtgärda det på din server
Servern måste lägga till rätt headers i sina svar, inklusive felsvar.
För den faktiska begäran ska den skicka:
Access-Control-Allow-Origin: https://myapp.com(din frontends exakta origin, utan avslutande snedstreck)Vary: Origin, om värdet beror på vilken origin som frågade
För preflight-begäran OPTIONS svarar du med en lyckad status (200 eller 204) och:
Access-Control-Allow-Origin: https://myapp.comAccess-Control-Allow-Methods: GET, POST, PUT, PATCH, DELETEAccess-Control-Allow-Headers: Content-Type, Authorization(varje egen header du skickar)- Valfritt
Access-Control-Max-Age: 600, så att webbläsaren cachar preflighten en stund
De flesta ramverk har ett paket eller en inställning som gör detta. I Express är det paketet cors; i FastAPI är det CORSMiddleware; i ASP.NET Core är det AddCors; i Spring är det @CrossOrigin eller en CORS-konfiguration. En typisk Express-uppsättning:
import cors from "cors";
app.use(cors({
origin: ["https://myapp.com", "http://localhost:5173"],
credentials: true,
}));
Lägg CORS-hanteringen före dina rutter och autentisering, så att preflight-begäranden (som inte bär någon inloggning) inte avvisas med 401.
Med en AI-byggare, beskriv uppsättningen exakt:
Frontend på
https://myapp.comanropar API:t påhttps://api.myapp.comoch får ”Response to preflight request doesn't pass access control check”. Konfigurera CORS på API:t så att det tillåter exakthttps://myapp.comoch förhandsvisningens origin, tillåt GET, POST, PATCH, DELETE med headers Content-Type och Authorization, hantera OPTIONS före autentisering, och inkludera CORS-headers även i felsvar.
Steg 4: Hantera cookies och inloggningsuppgifter
Om din frontend skickar cookies (till exempel en inloggningssession) till en annan origin måste båda sidor vara överens:
- Frontend sätter
credentials: "include"ifetch, ellerwithCredentials: truei axios. - Servern skickar
Access-Control-Allow-Credentials: true. - Serverns
Access-Control-Allow-Originmåste vara den exakta originen, inte*.
Cookies mellan sajter kräver också SameSite=None; Secure på cookien, och vissa webbläsare begränsar tredjepartscookies ytterligare. Det är ännu en anledning att föredra lösningen i steg 5.
Steg 5: Undvik CORS med en uppsättning på samma origin
Ofta är den renaste lösningen att inte göra några cross-origin-begäranden alls. Servera API:t från samma origin som sidan, till exempel på https://myapp.com/api/...:
- I utveckling kan de flesta utvecklingsservrar agera proxy. Vites inställning
server.proxykan vidarebefordra/apitill din backend på en annan port, så att webbläsaren bara pratar med en origin. - I produktion routar du
/apitill backenden via hostens rewrite- eller proxyinställningar, eller servar frontend och API från en och samma server.
Frontend anropar sedan en relativ sökväg som fetch("/api/orders"). Det finns ingen cross-origin-begäran, ingen preflight över origins och inga cookie-huvudvärk. Det innebär också att du inte hårdkodar en API-domän som skiljer sig mellan förhandsvisning och produktion.
Ändra frontend så att den anropar backenden med relativa /api-sökvägar i stället för en full URL, och ställ in en utvecklingsproxy så att /api vidarebefordras till API-servern. Ta sedan bort de CORS-inställningar vi inte längre behöver.
Vad du inte ska göra
mode: "no-cors"ifetch. Det förbigår ingenting; det ger din kod ett tomt, oläsbart svar.- Webbläsartillägg som stänger av CORS. De ändrar bara din webbläsare. Varje besökare ser fortfarande felet.
- Offentliga ”CORS-proxy”-tjänster för riktiga appar. De kan läsa och ändra allt som passerar genom dem, och de går ner.
Access-Control-Allow-Origin: *på ett API som använder inloggning. Det fungerar inte med inloggningsuppgifter ändå, och är fel standard för privat data.- Att spegla tillbaka vilken
Origin-header som helst med inloggningsuppgifter tillåtna. Det låter vilken webbplats som helst göra inloggade begäranden för dina användares räkning. Använd en tilläggslista i stället.
Vanliga orsaker i AI-byggda appar
| Situation | Lösning |
|---|---|
| Frontend anropar ett API från en tredje part med en hemlig nyckel | Flytta anropet till backenden |
| Fungerar i förhandsvisningen, misslyckas på den publicerade domänen | Lägg till de publicerade och egna domänernas origins i tilläggslistan, eller använd relativa /api-sökvägar |
| Fel bara vid POST, PUT eller DELETE | Preflight hanteras inte; lägg till OPTIONS-hantering och tillåtna headers |
| Felet uppstod efter att inloggning lades till | Inloggningsuppgifter kräver en exakt origin och Allow-Credentials |
| ”CORS-fel” men nätverksfliken visar 500 | Åtgärda serverfelet först |
API-URL hårdkodad till localhost | Använd relativa sökvägar eller en inställning per miljö |
CORS i Mythex
När ett Mythex-projekt har både en webbplats och en API-server körs båda som tjänster i samma projekt, och du kan växla mellan dem i förhandsvisningen. Om du ber agenten att låta frontend anropa backenden via en relativ /api-sökväg, proxad i utveckling, undviker du de flesta CORS-problem. Om du verkligen behöver cross-origin-anrop, ge agenten det exakta felet från konsolen och de origins som är inblandade. Kontrollera resultatet även på den publicerade appen, eftersom dess adress skiljer sig från förhandsvisningen. Se Multi-service-appar och API-backends i dokumentationen, samt våra guider om felsökning av en AI-byggd app och frontend kontra backend.
CORS-checklista
- Läst hela konsolfelet och den misslyckade begärans statuskod
- Utesluten en dold 404 eller 500
- API:er med hemliga nycklar anropas från backenden, inte webbläsaren
- Servern skickar
Access-Control-Allow-Originmed exakta tillåtna origins -
OPTIONS-preflight besvarad med tillåtna metoder och headers, före autentisering - CORS-headers finns även i felsvar
- Inloggningsuppgifter: exakt origin,
Allow-Credentials: trueoch rätt cookie-inställningar - Förhandsvisningens, den publicerade och egna domänens origins täckta, eller relativa
/api-sökvägar används - Inga
no-cors, offentliga proxyer eller genvägar som speglar vilken origin som helst
Frågor
Vad betyder ett CORS-fel?
Din sida, laddad från en origin, försökte läsa ett svar från en annan origin, och den serverns svar saknade headers som tillåter det. Webbläsaren blockerar din kod från att läsa svaret. Lösningen finns på servern, eller i hur begäran routas, inte i frontend-koden.
Kan jag åtgärda ett CORS-fel från frontend?
Inte på riktigt. Inställningar som mode: 'no-cors' döljer bara svaret för din kod. Du åtgärdar det genom att låta servern skicka rätt Access-Control-Allow-Origin-header, eller genom att anropa API:t från din egen backend eller en proxy på samma origin.
Är Access-Control-Allow-Origin: * säkert?
Det är bra för publik data som vem som helst får läsa, till exempel ett publikt API utan inloggning. Det kan inte användas med cookies eller andra inloggningsuppgifter, och för privata API:er bör du lista de exakta origins som tillåts.
Varför fungerar begäran i Postman eller curl men inte i webbläsaren?
CORS tillämpas bara av webbläsare. Verktyg som Postman och curl tillämpar det inte, så en begäran kan lyckas där och ändå blockeras när sidans JavaScript gör den.
Vad är en preflight-begäran?
För begäranden som inte är enkla, till exempel en JSON-POST eller en med en Authorization-header, skickar webbläsaren först en OPTIONS-begäran för att fråga servern vilka metoder och headers som tillåts. Om OPTIONS-begäran misslyckas eller saknar rätt headers skickas aldrig den riktiga begäran.