Hoppa till innehåll

Så fixar du CORS-fel i AI-genererade appar

CORS är en webbläsarmekanism, inte ett serverfel. Därför fungerar Postman men din driftsatta app gör det inte. Den här guiden visar steg för steg hur du löser det på rätt sätt.

CORS är en webbläsarmekanism. Varje gång din app försöker skicka en förfrågan till en annan host frågar webbläsaren servern om det är tillåtet. Det är inte en bugg i din kod — det är ett säkerhetslager inbyggt i varje webbläsare. Problemet är att de flesta aldrig lärde sig hur det fungerar.

Det är kombinationen av AI-genererad kod och publik driftsättning som fäller de flesta. På localhost fungerade allt eftersom frontend och backend låg på samma adress. Efter driftsättning ligger de på olika domäner — och webbläsaren blockerar förfrågningarna.

Den här artikeln är en praktisk steg-för-steg-guide. Jag förklarar vad CORS egentligen är, varför AI-verktyg gör det värre, och hur du fixar det en gång för alla — med kod du kan kopiera och använda direkt.

Vad CORS egentligen är

CORS (Cross-Origin Resource Sharing) är en säkerhetsmekanism i webbläsaren, inte ett serverfel. Så här fungerar det: varje gång din applikation försöker skicka en HTTP-förfrågan till en annan origin (en annan domän, port eller protokoll) frågar webbläsaren först målservern om det är tillåtet.

På localhost kör din frontend och backend vanligtvis på samma adress — till exempel http://localhost:3000. Det är same-origin — samma domän, samma port, samma protokoll. Webbläsaren ser inget problem eftersom förfrågan går till samma host. Det är därför allt fungerar under utveckling.

Efter driftsättning ligger din frontend på https://minapp.com och din backend på https://api.minapp.com eller en helt annan domän. Det är cross-origin. Och det är här webbläsaren kliver in.

Innan webbläsaren skickar din faktiska förfrågan (POST, PUT, DELETE) skickar den först en så kallad preflight-förfrågan — en OPTIONS-förfrågan till samma URL. Den frågar i princip: “Hej server, får frontend från domän X skicka POST-förfrågningar med de här headerna?” Om servern inte svarar med rätt CORS-headers blockerar webbläsaren förfrågan innan den ens skickas.

Det viktigaste att förstå: CORS är en webbläsarmekanism. Postman, curl, server-till-server-förfrågningar — ingen av dem tillämpar CORS. Därför kan ditt API fungera perfekt i Postman medan det kastar fel i webbläsaren. Det är inte en API-bugg — det är webbläsaren som gör sitt jobb.

CORS-kaskaden: så gör AI det värre

Så här ser det typiska scenariot ut: du ser ett CORS-fel i konsolen. Du säger till AI:n “fixa CORS”. AI:n ändrar något i serverkoden. CORS-felet försvinner — men nu är något annat trasigt. Du säger till AI:n “fixa det”. AI:n skriver om en annan del av koden. Och så börjar kaskaden.

Jag har sett det här på nära håll hos kunder: att låta AI:n “fixa CORS” skrev om serverkoden och förstörde importer, databasfrågor och svarsformatering. Tre dagar att ångra det AI:n gjorde på sekunder.

Problemet är grundläggande: AI:n förstår inte gränsen mellan frontend och backend. Den vet inte vilken kod som körs i webbläsaren och vilken som körs på servern. När du ber den fixa CORS ändrar AI:n ofta frontend (lägger till mode: 'no-cors' i fetch) eller serverkoden på sätt som förstör allt annat.

Det värsta AI gör:

  • Lägger till Access-Control-Allow-Origin: * överallt — ett wildcard istället för specifika domäner. Farligt i produktion.
  • Hanterar inte OPTIONS-förfrågningar — preflight-förfrågan förblir obesvarad, så webbläsaren blockerar allt.
  • Lägger till mode: 'no-cors' i fetch på frontend — det döljer problemet i stället för att lösa det. Svaret blir “opaque” och du kan inte läsa någon data.
  • Ändrar fungerande kod medan den försöker fixa något den inte förstår — det är kaskaden.

När saker går sönder reagerar folk instinktivt: de fortsätter prompta. “Fixa det här.” “Nu fungerar inte det där.” “Ångra den senaste ändringen men behåll CORS-fixen.” Varje ny prompt gör saken värre eftersom AI:n inte minns varför koden såg ut som den gjorde.

Steg-för-steg-fix

Steg 1: Kontrollera det verkliga felet

De flesta tittar på CORS-felet i webbläsarens konsol och antar att det är ett CORS-problem. Men ofta är det verkliga felet någon annanstans. Öppna fliken Network i DevTools, inte Console.

Hitta den misslyckade förfrågan. Klicka på den och kontrollera svarskoden. Om du ser 500 Internal Server Error kraschade din server — och eftersom den kraschade lade den inte till CORS-headers i svaret. Webbläsaren ser den saknade Access-Control-Allow-Origin-headern och visar ett CORS-fel, men det verkliga problemet är ett serverfel.

Om endpointen ger fel (500) läggs Access-Control-Allow-Origin vanligtvis inte till. Fixa serverfelet, så försvinner “CORS-felet” av sig självt.

Steg 2: Rätt sätt att konfigurera CORS (Express.js)

Här är hur ett CORS-middleware borde se ut på en Express.js-server. Notera att vi anger specifika domäner istället för wildcards, hanterar OPTIONS-förfrågan och ställer in credentials:

✓ Korrekt CORS-konfiguration
cors-middleware.js
const allowedOrigins = ['https://yourapp.com', 'https://app.yourapp.com'];

function corsMiddleware(req, res, next) {
  const origin = req.headers.origin;
  if (allowedOrigins.includes(origin)) {
    res.setHeader('Access-Control-Allow-Origin', origin);
    res.setHeader('Access-Control-Allow-Methods',
      'GET, POST, PUT, DELETE, OPTIONS');
    res.setHeader('Access-Control-Allow-Headers',
      'Content-Type, Authorization');
    res.setHeader('Access-Control-Allow-Credentials',
      'true');
  }
  if (req.method === 'OPTIONS')
    return res.status(204).end();
  next();
}

Steg 3: Vad AI genererar (fel)

Och här är vad AI:n vanligtvis genererar när du ber den “fixa CORS”. Det ser enkelt ut, men är fullt av problem:

✗ Vad AI genererar
server.js
app.use((req, res, next) => {
  res.header('Access-Control-Allow-Origin', '*');
  next();
});
// No OPTIONS handling
// Wildcard in production
// No credentials support
// No Allow-Methods or Allow-Headers

Skillnaderna är kritiska: wildcard * innebär att vilken webbplats som helst i världen kan skicka förfrågningar till ditt API. Ingen OPTIONS-hantering innebär att preflight-förfrågningar inte fungerar. Ingen Allow-Credentials innebär att cookies och tokens inte skickas. Det här är inte “fixat” — det är ett öppet säkerhetshål.

Steg 4: CORS i Supabase Edge Functions

Om du använder Supabase Edge Functions (Deno) måste CORS hanteras manuellt i varje funktion — eller, ännu bättre, centraliseras i en enda hjälpfil. Här är det korrekta mönstret:

✓ Supabase Edge Function med CORS
supabase/functions/my-function/index.ts
const corsHeaders = {
  'Access-Control-Allow-Origin': 'https://yourapp.com',
  'Access-Control-Allow-Methods': 'POST, OPTIONS',
  'Access-Control-Allow-Headers':
    'Content-Type, Authorization',
};

Deno.serve(async (req) => {
  if (req.method === 'OPTIONS')
    return new Response(null, {
      status: 204,
      headers: corsHeaders
    });

  // Your logic here
  const data = { message: 'Hello' };

  return new Response(
    JSON.stringify(data),
    {
      headers: {
        ...corsHeaders,
        'Content-Type': 'application/json'
      }
    }
  );
});

Steg 5: Centralisera CORS-konfigurationen

En fil, ett ställe. CORS-konfigurationen borde ligga på ett enda ställe i hela ditt projekt — inte spridas ut över varje endpoint och varje funktion. Skapa en fil cors.js (eller cors.ts) och importera den överallt där den behövs.

Lås samtidigt fast JSON-svarsformatet — varje endpoint borde returnera data i samma format. Håll din startfil liten — den borde bara importera middleware och starta servern. All affärslogik hör hemma i separata filer.

På så sätt, när du behöver ändra tillåtna origins eller lägga till en ny header, gör du det på ett ställe, och ändringen fungerar överallt. Brist på centralisering är en av huvudorsakerna till att AI-appar fungerar lokalt men misslyckas i produktion.

Steg 6: Felsök knepiga fall

Ibland ser allt korrekt ut och CORS fungerar ändå inte. Här är de vanligaste fällorna:

  • URL:er som inte matchar: https://minapp.com är inte samma sak som https://www.minapp.com. Se upp med avslutande snedstreck — webbläsaren skickar Origin-headern utan avslutande snedstreck, så om din lista över tillåtna origins innehåller https://minapp.com/ kommer strängjämförelsen att misslyckas.
  • no-cors-läge i fetch: Om någon (eller AI) lade till mode: 'no-cors' i en fetch-förfrågan kastar webbläsaren inget fel — men svaret blir “opaque”. Du kan inte läsa status, headers eller body. Det här är ingen fix — det är att sopa problemet under mattan.
  • Blandning av HTTP och HTTPS: http:// och https:// är olika origins. Om din frontend är på HTTPS och din backend på HTTP blockerar CORS förfrågan, och dessutom kan webbläsaren blockera blandat innehåll.
  • Dev-proxy vs. produktion: Många ramverk (React, Vue, Next.js) använder en proxy i utvecklingsläge som maskerar cross-origin-förfrågningar. I produktion finns inte den proxyn — och plötsligt smäller CORS till. Därför dyker CORS-fel bara upp efter driftsättning.

Vad AI-verktyg gör fel med CORS

AI-kodverktyg — Cursor, Claude Code, Copilot och andra — är otroligt effektiva på att generera kod. Men CORS är ett område där de gång på gång misslyckas. Varför? Jo, för att CORS är ett konfigurations- och arkitekturproblem, inte ett problem med kodlogik. AI är utmärkt på att skriva logik, men dålig på att förstå hur saker fungerar efter driftsättning.

Här är de återkommande mönstren jag ser hos kunder:

  • AI redigerar serverkod när den bara borde röra frontend — och tvärtom. Den förstår inte vilken kod som körs var. Den föreslår ofta ändringar på båda sidor, vilket skapar inkonsekvenser.
  • AI använder wildcard * i produktion — vilket inte bara är farligt utan gör det omöjligt att använda credentials (cookies, tokens) i förfrågningar.
  • AI hanterar inte preflight OPTIONS-förfrågningar — vilket innebär att POST-, PUT- och DELETE-förfrågningar blockeras av webbläsaren, även om CORS-headers är korrekt inställda på vanliga svar.
  • AI känner inte till credentials-läget — när du använder credentials: 'include' i fetch måste servern returnera Access-Control-Allow-Credentials: true och kan inte använda wildcard * som origin. Det här sambandet förstår AI nästan aldrig.
  • Folk fortsätter prompta istället för att fixa strukturen — när CORS inte fungerar är den naturliga reflexen “fixa det här”. Men varje ny prompt utan förståelse för problemet genererar mer kod som döljer problemet i stället för att lösa det. Det är kaskaden jag beskrev ovan.

Den bästa strategin: be inte AI:n fixa CORS. Förstå problemet själv, skriv konfigurationen manuellt (eller använd koden från den här artikeln) och säg åt AI:n att hålla sig borta från konfigurationsfilerna.

Produktionsklar CORS-checklista

Innan du driftsätter din applikation, gå igenom dessa punkter. Var och en är en potentiell källa till CORS-fel i produktion. Om en inte är uppfylld kan din app gå sönder på sätt som är svåra att diagnostisera.

  • Specifika tillåtna origins. Använd aldrig * i produktion. Lista varje domän din frontend kan skicka förfrågningar från.
  • Hantera OPTIONS-preflight explicit. Varje endpoint måste svara på preflight med status 204 och korrekta CORS-headers. Utan detta går POST/PUT/DELETE inte igenom.
  • Ställ in Allow-Methods och Allow-Headers. Webbläsaren kontrollerar om metoden och headers du använder är tillåtna. Om du inte listar dem blockeras förfrågan.
  • Hantera credentials korrekt. Om du använder cookies eller tokens måste du ställa in Access-Control-Allow-Credentials: true och du kan inte använda wildcard origin.
  • Centralisera CORS i en hjälpfil. En ändring, ett ställe. Sprid inte konfiguration över filer.
  • Testa med driftsatt frontend, inte bara localhost. CORS beter sig annorlunda på localhost. Testa från den riktiga domänen efter varje driftsättning.
  • 5xx-fel returnerar också CORS-headers. Om din felhanterare inte lägger till CORS-headers kommer varje serverfel att se ut som ett CORS-fel i webbläsaren.
  • Inga URL:er som inte matchar. Kontrollera avslutande snedstreck, www vs. icke-www, http vs. https. Varje skillnad är en egen origin.
  • Strukturerad loggning för CORS-fel. Logga avvisade förfrågningar med origin, metod och headers. Utan det är felsökning i produktion gissning.
  • Självtest efter varje driftsättning. Ett enkelt skript som skickar en cross-origin-förfrågan till ditt API och verifierar att svaret innehåller korrekta CORS-headers.

Vanliga frågor

Varför fungerar min app på localhost men får CORS-fel i produktion?

På localhost kör frontend och backend vanligtvis på samma adress (t.ex. http://localhost:3000), så webbläsaren behandlar det som same-origin och tillämpar inte CORS-regler. Efter driftsättning är frontend och backend på olika domäner — det är cross-origin och webbläsaren börjar kontrollera CORS-headers. Dessutom använder många ramverk en dev-proxy som maskerar cross-origin — den proxyn finns inte i produktion.

Borde jag använda Access-Control-Allow-Origin: * ?

Bara för helt publika API:er som inte kräver autentisering — t.ex. publika väderdata eller växelkurser. I alla andra fall, använd en lista med specifika domäner. Kom ihåg: wildcard * och Access-Control-Allow-Credentials: true kan inte samexistera. Webbläsaren avvisar svaret. Om din applikation använder cookies, JWT-tokens eller någon form av session är wildcard inte ett alternativ.

Är CORS ett frontend- eller backendproblem?

CORS är en backendkonfiguration som utlöses av frontend. Felet dyker upp i webbläsaren (frontend), men lösningen finns på servern (backend). Servern måste returnera korrekta Access-Control-Allow-*-headers för att webbläsaren ska tillåta förfrågan. Du kan inte "fixa CORS" enbart med ändringar i frontendkoden — det enda du kan göra på klientsidan är att dölja problemet (t.ex. mode: 'no-cors'), vilket är värre.

Varför fungerar Postman men inte min webbläsare?

Postman är inte en webbläsare. Webbläsare tillämpar CORS — API-klienter gör det inte. Postman, curl, Insomnia, server-till-server-förfrågningar — ingen av dem skickar preflight-förfrågningar eller kontrollerar Access-Control-Allow-Origin-headers. Det är en ren webbläsarmekanism. Om ditt API fungerar i Postman men inte i webbläsaren är det 100% ett CORS-konfigurationsproblem på servern — inte själva API:et.

Min AI fixade CORS men nu är andra saker trasiga

Det här är CORS-kaskaden. AI:n förstår inte sammanhanget i ditt projekt. När du ber den fixa CORS ändrar den ofta filer som inte borde röras — ändrar importer, modifierar svarsformat, skriver om middleware. Varje ny fix gör saken värre. Lösningen: rulla tillbaka till läget före AI:ns "fix" (använd git), förstå CORS-problemet med hjälp av den här artikeln och skriv konfigurationen manuellt. Låt inte AI:n redigera CORS-konfigurationsfilerna.

CORS fixat men något annat är trasigt?

CORS-fel är ofta bara toppen av isberget. Om din AI-app har problem efter driftsättning, låt oss prata — jag hjälper dig från prototyp till produktion.

Boka ett gratis samtal →
Gratis konsultation Utan förpliktelser Svar inom 24h