<EbeneX/>
Web · Updated 3. März 2026

CORS

Definition

Ein Browser-Sicherheitsmechanismus, der kontrolliert, welche Webseiten Anfragen an eine andere Domain stellen dürfen – und wie Server diese Anfragen erlauben oder ablehnen.

Fortgeschritten 3 Min. Lesezeit EN: Cross-Origin Resource Sharing (CORS)

Einfach erklärt

Browser haben eine eingebaute Sicherheitsregel: Eine Webseite darf standardmäßig nur Anfragen an dieselbe Domain stellen, von der sie geladen wurde (Same-Origin-Policy). frontend.example.com darf also nicht einfach api.other.com aufrufen.

CORS ist der Mechanismus, mit dem Server diese Einschränkung gezielt aufheben können. Der Server sagt dem Browser: „Anfragen von frontend.example.com sind erlaubt.” Der Browser prüft das und lässt die Anfrage durch.

Zwei wichtige Grundregeln:

  1. CORS ist ein Browser-Mechanismus – Server-zu-Server-Kommunikation (Node.js, Python, curl) kennt kein CORS
  2. Die Lösung liegt immer auf dem Server – der Browser blockiert nur, weil der Server keine CORS-Header schickt

Was ist eine “Origin”?

Eine Origin besteht aus Schema + Domain + Port. Alle drei müssen übereinstimmen:

URL AURL BGleiche Origin?
https://example.comhttps://example.com/api✅ Ja
https://example.comhttp://example.com❌ Nein (Schema)
https://example.comhttps://api.example.com❌ Nein (Subdomain)
https://example.comhttps://example.com:3000❌ Nein (Port)

Technischer Deep Dive

Die wichtigsten CORS-Headers

# Server-Antwort
Access-Control-Allow-Origin: https://frontend.example.com
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Headers: Content-Type, Authorization
Access-Control-Max-Age: 86400  # Preflight 24h cachen
Access-Control-Allow-Credentials: true  # Nur wenn Cookies nötig

CORS in Express.js konfigurieren

import cors from 'cors';

// Dynamische Origin-Validierung (sicherer als Whitelist)
const allowedOrigins = [
  'https://frontend.example.com',
  'https://app.example.com',
  process.env.NODE_ENV === 'development' ? 'http://localhost:3000' : null,
].filter(Boolean);

app.use(cors({
  origin: (origin, callback) => {
    if (!origin || allowedOrigins.includes(origin)) {
      callback(null, true);
    } else {
      callback(new Error(`CORS: Origin ${origin} nicht erlaubt`));
    }
  },
  methods: ['GET', 'POST', 'PUT', 'DELETE'],
  allowedHeaders: ['Content-Type', 'Authorization'],
  credentials: true,
}));

CORS in FastAPI (Python)

from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware

app = FastAPI()

app.add_middleware(
    CORSMiddleware,
    allow_origins=["https://frontend.example.com"],
    allow_credentials=True,
    allow_methods=["GET", "POST", "PUT", "DELETE"],
    allow_headers=["Content-Type", "Authorization"],
    max_age=86400,
)

Preflight-Flow

Browser → OPTIONS /api/data (Preflight)
          Headers: Origin, Access-Control-Request-Method, Access-Control-Request-Headers
Server  → 200 OK
          Headers: Access-Control-Allow-Origin, Access-Control-Allow-Methods, ...
Browser → POST /api/data (eigentliche Anfrage)
Server  → 200 OK + Daten

Preflight wird ausgelöst bei: nicht-standard Methoden (PUT, DELETE), custom Headers (Authorization), Content-Type außer text/plain, multipart/form-data, application/x-www-form-urlencoded.

Sicherheitsrisiken bei falschem CORS

// ❌ Gefährlich: Jede Origin erlaubt
app.use(cors({ origin: '*' }));

// ❌ Noch gefährlicher: Origin aus Request übernehmen
app.use((req, res) => {
  res.header('Access-Control-Allow-Origin', req.headers.origin); // Nie so!
});

// ❌ Wildcard + Credentials funktioniert nicht (Browser blockiert)
app.use(cors({ origin: '*', credentials: true }));

// ✅ Korrekt: Explizite Whitelist
app.use(cors({ origin: ['https://app.example.com'] }));

Debugging-Workflow

1. Browser-Konsole: Welcher Header fehlt?
   "No 'Access-Control-Allow-Origin' header" → Origin nicht erlaubt
   "Response to preflight has invalid HTTP status code 404" → OPTIONS-Route fehlt

2. curl testen (kein CORS):
   curl -H "Origin: https://frontend.example.com" \
        -H "Access-Control-Request-Method: POST" \
        -X OPTIONS https://api.example.com/data -v

3. Response-Headers prüfen:
   Access-Control-Allow-Origin: https://frontend.example.com ✅
   Access-Control-Allow-Methods: GET, POST ✅

Häufige Fehler

FehlerUrsacheLösung
* + credentials: trueNicht erlaubtSpezifische Origin angeben
Preflight 404OPTIONS-Route fehltCORS-Middleware vor Routen
Subdomain nicht erlaubtapi.example.comexample.comSubdomain explizit hinzufügen
Localhost in ProductionVergessen zu entfernenEnv-Variable für Origins nutzen

CORS ist wie ein Türsteher an einem Clubeingang: Dein Browser fragt: 'Darf frontend.example.com rein?' Der Server (Club) antwortet: 'Ja, aber nur mit Gästeliste-Eintrag' oder 'Nein, nicht auf der Liste.' Der Türsteher (Browser) lässt dich nur rein, wenn der Club es ausdrücklich erlaubt.

Browsers blockieren standardmäßig Anfragen an andere Domains (Same-Origin-Policy)

Server können mit CORS-Headers bestimmte Domains explizit erlauben

Preflight-Anfragen (OPTIONS) prüfen vorab, ob eine Anfrage erlaubt ist

Frontend-Backend-Trennung

React-App auf frontend.example.com ruft API auf api.example.com auf – CORS muss konfiguriert sein

KI-API-Integration

Browser-basierte KI-Tools, die direkt OpenAI oder andere APIs aufrufen

CDN-Assets

Fonts, Bilder oder Skripte von einer anderen Domain laden

Warum bekomme ich einen CORS-Fehler, obwohl mein Server antwortet?

CORS wird vom Browser erzwungen, nicht vom Server. Der Server antwortet – aber der Browser blockiert die Antwort, weil der Server keine CORS-Header gesetzt hat. Die Lösung liegt immer auf der Server-Seite: die richtigen Access-Control-Headers setzen.

Was ist eine Preflight-Anfrage?

Vor bestimmten Anfragen (z. B. mit custom Headers oder nicht-standard Methoden) sendet der Browser automatisch eine OPTIONS-Anfrage. Der Server muss darauf mit den erlaubten Methoden und Headers antworten. Erst dann sendet der Browser die eigentliche Anfrage.

Ist CORS ein Sicherheitsproblem?

CORS ist ein Sicherheitsmechanismus, kein Problem. Falsch konfiguriertes CORS (z. B. Access-Control-Allow-Origin: *) kann aber ein Sicherheitsproblem sein, da es jeder Website erlaubt, Anfragen zu stellen.

Dein persönliches Share-Bild für Instagram – 1080×1080px, bereit zum Posten.