Das kennen wir alle: Sie senden eine API-Anfrage, warten auf die Antwort, und plötzlich erscheint der „CORS-Fehler” in Ihrer Browserkonsole.
Für viele Entwickelnde ist der erste Instinkt, eine schnelle Lösung zu finden: Access-Control-Allow-Origin: * hinzufügen und weiter. Dieser Ansatz verfehlt jedoch den Kern der Sache völlig. CORS ist nicht nur eine weitere Konfigurationshürde, sondern einer der wichtigsten Browser-Sicherheitsmechanismen, die je entwickelt wurden.
CORS, oder Cross-Origin Resource Sharing, existiert, um Benutzer zu schützen, während es legitime domänenübergreifende Kommunikation zwischen Webanwendungen ermöglicht. Dennoch wird es oft missverstanden, falsch konfiguriert oder wie ein Fehler behandelt, den man „umgehen“ muss.
Aber nicht mehr.
In diesem Leitfaden gehen wir über die Grundlagen hinaus. Sie erfahren:
- Warum CORS existiert und wie es sich aus der Same-Origin Policy (SOP) entwickelt hat
- Wie Browser und Server tatsächlich den Cross-Origin-Zugriff verhandeln
- Was dazu führt, dass einige CORS-Setups fehlschlagen, selbst wenn sie „richtig aussehen“
- Wie man Preflight-Anfragen, Credentials und Browser-Eigenheiten sicher handhabt
Am Ende werden Sie nicht nur wissen, wie man CORS konfiguriert, sondern auch verstehen, warum es sich so verhält, wie es sich verhält, und wie Sie Ihre APIs sicher darum herum gestalten.
Was ist CORS (und warum es existiert)
CORS ist ein Browser-Sicherheitsstandard, der definiert, wie Webanwendungen von einem Origin sicher auf Ressourcen von einem anderen zugreifen können.
Um die CORS-Sicherheit zu verstehen, müssen Sie zunächst wissen, warum es geschaffen wurde.
Lange bevor APIs und Microservices das Web eroberten, folgten Browser einer einfachen Regel, der Same-Origin Policy (SOP).
Diese Richtlinie besagte, dass eine Webseite Daten nur vom selben Origin senden und empfangen konnte, d.h. dasselbe Protokoll, dieselbe Domain und denselben Port.
Zum Beispiel:
Diese Einschränkung war im frühen Web absolut sinnvoll, als die meisten Websites monolithisch waren. Eine einzige Website hostete ihr Frontend, Backend und ihre Assets alle unter einer Domain.
Doch mit der Entwicklung des Webs, mit APIs, Microservices und Drittanbieter-Integrationen, wurde diese Regel zu einem Hindernis. Entwickelnde benötigten Frontend-Anwendungen, um mit anderen Domains zu kommunizieren, wie zum Beispiel:
- www.example.com kommuniziert mit api.example.com
- Ihre App verbindet sich mit einem CDN oder Analytics-Endpunkt
- Web-Clients rufen Drittanbieter-APIs auf (wie Stripe oder Google Maps)
Die Same-Origin Policy wurde zu einer Mauer, die moderne, verteilte Architekturen blockierte.
Hier kam Cross-Origin Resource Sharing (CORS) ins Spiel.
Anstatt Browser-Einschränkungen vollständig aufzuheben, führte CORS eine kontrollierte Lockerung der SOP ein. Es schuf eine sichere Möglichkeit für Browser und Server, domänenübergreifend zu kommunizieren, sicher und nur wenn beide Seiten zustimmen.
Stellen Sie es sich so vor: SOP ist eine verschlossene Tür, die niemanden hereinlässt, und CORS ist dieselbe Tür, aber mit einer Gästeliste und einem Türsteher, der Ausweise kontrolliert.
Dieses Gleichgewicht zwischen Flexibilität und Schutz macht die CORS-Konfiguration für jede moderne Webanwendung entscheidend.
Die Same-Origin Policy (SOP) verstehen
Bevor wir tiefer in die CORS-Konfiguration eintauchen, ist es unerlässlich, ihre Grundlage zu verstehen: die Same-Origin Policy (SOP).
Wie bereits erwähnt, ist die SOP die erste Verteidigungslinie des Browsers gegen bösartiges Verhalten im Web. Sie verhindert, dass eine Website frei auf die Daten einer anderen zugreift, was sensible Informationen wie Cookies, Authentifizierungs-Tokens oder persönliche Daten preisgeben könnte.
So funktioniert es in der Praxis: Wenn eine Webseite in Ihrem Browser geladen wird, wird ihr ein Ursprung zugewiesen, der auf drei Elementen basiert: dem Protokoll, dem Host und dem Port:
https:// api.example.com :443
^ ^ ^
Protokoll Host Port
Zwei URLs gelten nur dann als same-origin, wenn alle drei dieser Teile übereinstimmen. Andernfalls behandelt der Browser sie als cross-origin.
Diese einfache Regel verhindert schädliche Cross-Site-Aktionen. Ohne sie könnte eine beliebige Website Ihr Online-Banking-Dashboard in einem unsichtbaren Frame laden, Ihren Kontostand auslesen und an einen Angreifer senden, alles ohne Ihre Zustimmung.
Kurz gesagt, die SOP dient dazu, Inhalte zwischen verschiedenen Websites zu isolieren, um sicherzustellen, dass jeder Ursprung eine eigenständige Sicherheitszone ist.
Warum die SOP allein nicht ausreichte
Die Same-Origin Policy funktionierte perfekt, als Websites eigenständig waren. Doch als sich das Web zu einem Ökosystem aus APIs, Microservices und verteilten Architekturen entwickelte, wurde diese strikte Regel zu einer erheblichen Einschränkung.
Moderne Anwendungen mussten:
- Eigene APIs aufrufen, die auf verschiedenen Subdomains gehostet wurden (app.example.com → api.example.com)
- Assets von CDNs oder Drittanbieterdiensten abrufen
- Sich mit externen APIs wie Stripe, Firebase oder Google Maps integrieren
Unter SOP wurden diese legitimen Cross-Origin-Anfragen blockiert. Entwickelnde versuchten jede mögliche Umgehungslösung, einschließlich JSONP, Reverse-Proxys oder duplizierter Domains, doch diese Lösungen waren entweder unsicher oder extrem komplex.
Hier änderte CORS (Cross-Origin Resource Sharing) die Spielregeln.
CORS führte ein Handshake-System ein, das es Browsern und Servern ermöglichte, Vertrauen auszuhandeln. Anstatt die SOP zu brechen, erweiterte es diese und bot eine Möglichkeit, bestimmte Ursprünge für die Cross-Domain-Kommunikation sicher auf die Whitelist zu setzen.
Wie CORS funktioniert: Der Ablauf auf Protokollebene
Wie bereits erwähnt, wenn Ihr Browser eine Anfrage an einen anderen Ursprung sendet, tut er dies nicht einfach blind. Stattdessen folgt er einem klar definierten CORS-Protokoll: einem Hin- und Her-Gespräch zwischen Browser und Server, um festzustellen, ob die Anfrage zugelassen werden soll.
Im Kern funktioniert CORS über HTTP-Header. Der Browser fügt jeder Cross-Origin-Anfrage einen Origin-Header hinzu, der dem Server mitteilt, woher die Anfrage stammt. Der Server antwortet dann mit einem oder mehreren Access-Control-*-Headern, die definieren, was erlaubt ist.
Hier ist ein vereinfachtes Beispiel dieses Gesprächs:
# Request
GET /api/data HTTP/1.1
Host: api.example.com
Origin: https://app.example.com
# Response
HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://app.example.com
Content-Type: application/json
{"message": "Success"}
In diesem Fall erlaubt der Server dem Ursprung https://app.example.com explizit, auf seine Ressource zuzugreifen. Der Browser überprüft diese Antwort, bestätigt die Übereinstimmung und liefert die Daten an Ihr JavaScript.
Doch wenn die Ursprünge nicht übereinstimmen oder wenn die Antwort-Header fehlen oder falsch sind, blockiert der Browser die Antwort stillschweigend. Sie sehen die Daten nicht, sondern nur die frustrierende „CORS error“-Meldung in Ihrer Konsole.
Es ist wichtig zu beachten, dass CORS einen Server nicht per se sicherer macht. Stattdessen erzwingt es Regeln für die Interaktion zwischen Browsern und Servern, eine Sicherheitsebene, die sicherstellt, dass nur vertrauenswürdige Ursprünge auf geschützte Ressourcen zugreifen können.
Arten von CORS-Anfragen
CORS definiert zwei Haupttypen von Anfragen: einfache und Preflight-Anfragen. Der Unterschied liegt darin, wie viel Verifizierung der Browser vor dem Senden von Daten durchführt.
1. Einfache Anfragen
Eine einfache Anfrage ist der unkomplizierteste Typ. Sie wird von Browsern automatisch zugelassen, solange sie bestimmte Regeln befolgt:
- Verwendet eine dieser Methoden: GET, HEAD oder POST
- Beinhaltet nur bestimmte Header:
- Accept
- Accept-Language
- Content-Language
- Content-Type (aber nur application/x-www-form-urlencoded, multipart/form-data oder text/plain)
- Verwendet keine Benutzerdefinierten Header oder Streams
So sieht es aus:
# Request
GET /api/data HTTP/1.1
Host: api.example.com
Origin: https://app.example.com
# Response
HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://app.example.com
Content-Type: application/json
{"message": "This is the response data"}In diesem Fall:
- Der Browser fügt den Origin-Header automatisch hinzu.
- Der Server muss Access-Control-Allow-Origin mit einem passenden Origin zurückgeben.
- Wenn der Origin nicht übereinstimmt oder fehlt, blockiert der Browser die Antwort.
2. Preflight Requests
Interessanter wird es bei nicht-einfachen Anfragen (non-simple requests). Zum Beispiel, wenn Sie Methoden wie PUT, DELETE oder Benutzerdefinierte Header wie Authorization verwenden.
Bevor die eigentliche Anfrage gesendet wird, führt der Browser eine Preflight-Prüfung mittels einer OPTIONS-Anfrage durch. Dieser Schritt stellt sicher, dass der Server den beabsichtigten Vorgang explizit erlaubt.
Hier ist ein Beispiel:
# Preflight Request
OPTIONS /api/data HTTP/1.1
Host: api.example.com
Origin: https://app.example.com
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: content-type, authorization
# Preflight Response
HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://app.example.com
Access-Control-Allow-Methods: PUT, POST, GET, DELETE
Access-Control-Allow-Headers: content-type, authorization
Access-Control-Max-Age: 3600
# Actual Request (only sent if preflight succeeds)
PUT /api/data HTTP/1.1
Host: api.example.com
Origin: https://app.example.com
Content-Type: application/json
Authorization: Bearer token123
{"data": "update this resource"}In dieser Abfolge:
- Der Browser erkennt eine nicht-einfache Anfrage (non-simple request).
- Er sendet eine Preflight-OPTIONS-Anfrage, um die Erlaubnis für die eigentliche Methode und die Header einzuholen.
- Der Server antwortet mit den Methoden, Headern und Origins, die er erlaubt.
- Wenn die Preflight-Prüfung erfolgreich ist, sendet der Browser die eigentliche Anfrage. Andernfalls blockiert er sie.
Umgang mit Credentials in CORS
Beim Umgang mit APIs, die eine Authentifizierung wie Cookies, Tokens oder sessionbasierte Logins erfordern, verhält sich CORS anders.
Standardmäßig behandeln Browser Cross-Origin-Anfragen aus Sicherheitsgründen als nicht authentifiziert. Das bedeutet, dass Cookies oder HTTP-Authentifizierungs-Header nicht automatisch enthalten sind.
Um Anfragen mit Credentials sicher zu ermöglichen, müssen zwei wichtige Schritte übereinstimmen:
1. Der Client muss Credentials explizit erlauben:
fetch('https://api.example.com/data', {
credentials: 'include'
})2. Der Server muss sie explizit zulassen:
Access-Control-Allow-Credentials: true
Aber es gibt einen Haken, und zwar einen großen.
Wenn Access-Control-Allow-Credentials auf true gesetzt ist, können Sie keinen Wildcard (*) in Access-Control-Allow-Origin verwenden. Browser werden die Antwort ablehnen, wenn Sie dies versuchen.
Das liegt daran, dass die Erlaubnis für alle Ursprünge, authentifizierte Anfragen zu senden, den gesamten Zweck der CORS-Sicherheit untergraben würde. Es würde jeder Website im Internet den Zugriff auf private Daten ermöglichen, die an die Sitzung eines Benutzers gebunden sind.
Stattdessen sollten Sie dies vermeiden:
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: trueSie sollten immer einen spezifischen Ursprung verwenden:
Access-Control-Allow-Origin: https://yourapp.com
Access-Control-Allow-Credentials: trueWenn Ihre API mehrere vertrauenswürdige Domains bedient, können Sie den korrekten Origin-Header serverseitig dynamisch zurückgeben:
const allowedOrigins = ['https://app1.com', 'https://app2.com'];
const origin = req.headers.origin;
if (allowedOrigins.includes(origin)) {
res.setHeader('Access-Control-Allow-Origin', origin);
res.setHeader('Access-Control-Allow-Credentials', 'true');
}Dieser Ansatz stellt sicher, dass Ihre authentifizierten Anfragen sicher und beabsichtigt bleiben und nicht für jeden zugänglich sind, der es versucht.
Wie Browser bestimmen, welche Anfragen CORS-berechtigt sind
Bevor eine Anfrage überhaupt Ihren Server erreicht, entscheidet der Browser, ob sie unter die CORS-Regeln fällt.
Diese Entscheidung hängt vom Ursprung der Anfrage ab und davon, ob sie eine andere Domain, einen anderen Port oder ein anderes Protokoll anvisiert.
Zum Beispiel:
- Anfrage an https://api.example.com von einer Seite, die unter https://example.com bereitgestellt wird: ✅ CORS greift (andere Subdomain).
- Anfrage an https://example.com:3000 von https://example.com: ✅ CORS greift (anderer Port).
- Anfrage an https://example.com von der gleichen Domain und dem gleichen Port: ❌ CORS greift nicht.
Wenn der Browser erkennt, dass eine Anfrage ursprungsübergreifend ist, fügt er automatisch den Origin-Header in die Anfrage ein:
Origin: https://example.com
Dieser Header teilt dem Server mit, woher die Anfrage kam, und er ist das, was der Server verwendet, um zu entscheiden, ob der Zugriff erlaubt oder blockiert werden soll.
Fehlen in der Antwort die richtigen Header (wie Access-Control-Allow-Origin), blockiert der Browser einfach den Zugriff auf die Antwort, obwohl der Server technisch gesehen eine gesendet hat.
Das ist ein wichtiger Unterschied: Der Browser setzt CORS durch, nicht der Server.
Interne Sicherheitsprüfungen, XMLHttpRequest vs. Fetch und Browser-Unterschiede
Nicht alle Browser handhaben CORS auf die gleiche Weise, aber sie alle folgen dem gleichen Sicherheitsmodell: Vertraue niemals ursprungsübergreifenden Daten, es sei denn, dies ist explizit erlaubt.
Was sich unterscheidet, ist, wie streng sie die Regeln durchsetzen und auf welche APIs sie diese anwenden.
1. Die interne CORS-Sicherheitsprüfung
Wenn ein Browser eine Antwort auf eine ursprungsübergreifende Anfrage erhält, führt er einen internen Validierungsschritt durch, bevor er die Antwort Ihrem JavaScript-Code zugänglich macht.
Es prüft auf Header wie:
- Access-Control-Allow-Origin: muss mit dem anfragenden Origin übereinstimmen (oder in einigen Fällen * sein).
- Access-Control-Allow-Credentials: muss true sein, wenn Cookies oder Authentifizierungs-Tokens beteiligt sind.
- Access-Control-Allow-Methods und Access-Control-Allow-Headers: müssen mit dem ursprünglichen Preflight-Request übereinstimmen, falls einer gesendet wurde.
Wenn eine dieser Prüfungen fehlschlägt, löst der Browser keinen HTTP-Fehler aus, sondern blockiert einfach den Zugriff auf die Antwort und protokolliert einen CORS-Fehler in der Konsole.
Das erschwert das Debugging, da der eigentliche Netzwerk-Request trotzdem erfolgreich war, der Browser das Ergebnis jedoch aus Sicherheitsgründen verbirgt.
2. XMLHttpRequest vs. Fetch
Sowohl XMLHttpRequest als auch die moderne fetch()-API unterstützen CORS, verhalten sich jedoch geringfügig anders, wenn es um Credentials und Standardeinstellungen geht.
Bei XMLHttpRequest:
- Cookies und HTTP-Authentifizierung werden automatisch gesendet, wenn withCredentials auf true gesetzt ist.
- Das Preflight-Verhalten hängt davon ab, ob Benutzerdefinierte Header hinzugefügt werden.
Bei Fetch:
- Credentials (Cookies, HTTP-Authentifizierung) sind standardmäßig nicht enthalten.
- Sie müssen diese explizit aktivieren mittels:
fetch("https://api.example.com/data", {
credentials: "include"
});- fetch behandelt Redirects unter CORS auch strenger, da es Cross-Origin-Redirects nur folgt, wenn dies erlaubt ist.
Obwohl fetch sauberer und moderner ist, ist es auch weniger nachsichtig, wenn man einen Header vergisst oder eine Credential-Regel übersieht.
3. Browser-Unterschiede und Eigenheiten
Obwohl die CORS-Spezifikation Standard ist, implementieren Browser sie mit subtilen Unterschieden:
- Safari kann bei Cookies und authentifizierten Anfragen übermäßig streng sein, insbesondere wenn Third-Party-Cookies blockiert sind.
- Firefox cacht fehlgeschlagene Preflight-Responses manchmal länger als erwartet, was zu inkonsistenten Ergebnissen während des Testens führt.
- Chrome erzwingt CORS bei bestimmten Redirect-Ketten aggressiver als andere.
Aufgrund dieser Unterschiede kann eine Konfiguration, die in einem Browser perfekt funktioniert, in einem anderen stillschweigend fehlschlagen.
Deshalb ist es entscheidend, CORS-Setups browserübergreifend zu testen, insbesondere wenn Credentials oder Redirects beteiligt sind.
Serverseitige Handhabung des Origin-Headers
Während der Browser CORS erzwingt, findet die eigentliche Entscheidungsfindung auf dem Server statt.
Wenn der Browser einen Cross-Origin-Request sendet, fügt er immer den Origin-Header hinzu. Die Aufgabe des Servers ist es, diesen Header zu prüfen, zu entscheiden, ob er zugelassen werden soll, und die korrekten CORS-Header als Antwort zurückzugeben.
1. Validierung des Ursprungs
Eine typische Anfrage könnte wie folgt aussehen: Origin: https://frontend.example.com
Auf dem Server muss Ihr Code überprüfen, ob dieser Ursprung erlaubt ist. Der einfachste (und sicherste) Ansatz ist, eine Allowlist vertrauenswürdiger Domains zu pflegen:
const allowedOrigins = ["https://frontend.example.com", "https://admin.example.com"];
if (allowedOrigins.includes(req.headers.origin)) {
res.setHeader("Access-Control-Allow-Origin", req.headers.origin);
}Dies stellt sicher, dass nur bekannte Clients auf Ihre API zugreifen können, während andere keine CORS-Berechtigung erhalten.
Vermeiden Sie die Rückgabe von Access-Control-Allow-Origin: *, wenn Ihre API Cookies, Tokens oder andere Anmeldeinformationen verarbeitet.
2. Verarbeitung von Preflight-Anfragen
Bei OPTIONS-Preflight-Anfragen muss der Server mit der gleichen Sorgfalt antworten wie bei Hauptanfragen.
Eine vollständige Preflight-Antwort umfasst:
Access-Control-Allow-Origin: https://frontend.example.com
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Headers: Content-Type, Authorization
Access-Control-Max-Age: 86400Diese Header teilen dem Browser mit, was erlaubt ist und wie lange er diese Entscheidung cachen kann. Fehlen oder sind diese Header falsch, blockiert der Browser die nachfolgende Anfrage, selbst wenn Ihr Endpunkt selbst einwandfrei funktioniert.
3. Dynamische Konfiguration von CORS-Headern
In großen Systemen (wie Multi-Tenant-Plattformen oder APIs mit mehreren Clients) müssen die erlaubten Ursprünge möglicherweise dynamisch sein.
Zum Beispiel:
const origin = req.headers.origin;
if (origin && origin.endsWith(".trustedclient.com")) {
res.setHeader("Access-Control-Allow-Origin", origin);
}Dieses Muster erlaubt alle Subdomains einer vertrauenswürdigen Domain, während unbekannte Quellen weiterhin herausgefiltert werden.
Stellen Sie einfach sicher, dass Sie Ursprünge sorgfältig validieren und keine String-Matches auf Benutzereingaben ohne Einschränkungen durchführen, da sonst Angreifer Header fälschen könnten, die gültig aussehen.
4. Warum “Es funktioniert in Postman” nicht bedeutet, dass es korrekt konfiguriert ist
Eines der größten Missverständnisse bezüglich CORS ist folgendes: “Es funktioniert in Postman, also muss es ein Browserproblem sein.”
Postman erzwingt CORS überhaupt nicht, weil es kein Browser ist.
Das bedeutet, dass selbst eine komplett offene API ohne Access-Control-*-Header dort einwandfrei antwortet, aber in Chrome oder Firefox sofort fehlschlägt.
Wenn Ihre API also in Postman funktioniert, aber nicht in Ihrer Web-App, sind Ihre CORS-Header wahrscheinlich unvollständig oder falsch konfiguriert.
Häufige CORS-Fehlkonfigurationen (und wie man sie vermeidet)
1. Verwendung von Access-Control-Allow-Origin: * mit Anmeldeinformationen
Dies ist der häufigste und gefährlichste Fehler.
Wenn Ihre Antwort beides enthält:
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true…blockiert der Browser die Anfrage automatisch.
Die CORS-Spezifikation verbietet die Verwendung von Wildcards, wenn Anmeldeinformationen enthalten sind, da dies jeder Website den Zugriff auf Benutzerdaten ermöglichen würde, die an Cookies oder Authentifizierungs-Tokens gebunden sind.
Lösung: Geben Sie immer einen spezifischen Ursprung zurück, wenn Anmeldeinformationen verwendet werden:
Access-Control-Allow-Origin: https://app.example.com
Access-Control-Allow-Credentials: true2. Vergessen, Preflight-Anfragen zu verarbeiten
Viele APIs antworten korrekt auf GET und POST, vergessen aber die OPTIONS Preflight-Anfrage.
Wenn das passiert, erreicht der Browser Ihren tatsächlichen Endpunkt nie und blockiert die Hauptanfrage nach dem fehlgeschlagenen Preflight.
Lösung: Behandeln Sie OPTIONS-Anfragen explizit und antworten Sie mit den richtigen Headern:
if (req.method === "OPTIONS") {
res.setHeader("Access-Control-Allow-Origin", req.headers.origin);
res.setHeader("Access-Control-Allow-Methods", "GET,POST,OPTIONS");
res.setHeader("Access-Control-Allow-Headers", "Content-Type,Authorization");
return res.sendStatus(204);
}3. Falsch abgestimmte Request- und Response-Header
Ein weiteres subtiles Problem: Ihre Preflight-Anfrage könnte bestimmte Header anfordern, aber der Server erlaubt sie nicht explizit.
Zum Beispiel, wenn Ihre Anfrage Folgendes enthält:
Access-Control-Request-Headers: Authorization, Content-Type
…aber der Server antwortet nur mit:
Access-Control-Allow-Headers: Content-Type
…blockiert der Browser die Anfrage. Beide Listen müssen exakt übereinstimmen.
Lösung: Stellen Sie sicher, dass Ihre Access-Control-Allow-Headers jeden Header enthalten, den der Client senden könnte, insbesondere Authorization, Accept und Benutzerdefinierte Header.
4. Zurückgeben mehrerer Access-Control-Allow-Origin-Header
Einige falsch konfigurierte Proxys oder Frameworks senden mehrere Access-Control-Allow-Origin-Header (zum Beispiel einen statischen * und einen dynamischen Origin).
Browser behandeln dies als ungültig und blockieren die Anfrage vollständig.
Lösung: Geben Sie immer einen einzigen, gültigen Access-Control-Allow-Origin-Header zurück.
5. Methodenbeschränkungen vergessen
Wenn Sie nicht alle erlaubten Methoden in Access-Control-Allow-Methods aufnehmen, lehnen Browser legitime Anfragen ab.
Zum Beispiel könnte eine API PUT unterstützen, aber Ihre Preflight-Antwort erlaubt nur GET und POST.
Lösung: Listen Sie jede unterstützte Methode auf oder gleichen Sie Ihre API-Routen dynamisch ab, um Konsistenz zu gewährleisten.
6. Ignorieren von gecachten Preflight-Antworten
Moderne Browser cachen Preflight-Ergebnisse zur Leistungsoptimierung.
Wenn Ihr Server oder CDN jedoch Antworten ohne Variierung nach Origin cached, könnten Sie versehentlich die falschen CORS-Header an einen anderen Client senden.
Lösung: Verwenden Sie den Vary: Origin-Header, um sicherzustellen, dass Antworten pro Origin separat gecacht werden.
CORS-Probleme entstehen selten durch einen großen Fehler. Sie sind meist das Ergebnis mehrerer kleiner Diskrepanzen zwischen Browser-Erwartungen und Serverkonfiguration. Das Verständnis dieser Muster hilft Ihnen, endlose “CORS error” Debugging-Zyklen zu vermeiden.
CORS ist nicht der Feind, sondern das Missverständnis.
Auf den ersten Blick wirkt CORS wie eine unnötige Barriere oder eher wie ein Gatekeeper, der Anfragen blockiert und die Entwicklung verlangsamt.
Doch in Wirklichkeit ist es eine der wichtigsten Browser-Sicherheitsfunktionen, die je entwickelt wurden.
Sobald man versteht, wie es funktioniert, hört man auf, „CORS-Fehler“ als zufällige Ausfälle zu betrachten, sondern sie werden zu Signalen, dass Client und Server sich besser bezüglich Vertrauen, Headern oder Anmeldeinformationen abstimmen müssen.
Egal, ob Sie eine Single-Page-App oder ein verteiltes API-Ökosystem aufbauen, CORS ist Ihr Verbündeter, um Benutzer zu schützen, während es eine sichere Cross-Domain-Kommunikation ermöglicht.
Wenn Sie also das nächste Mal diese bekannte Konsolenmeldung sehen, greifen Sie nicht zum Wildcard. Lesen Sie die Header, verfolgen Sie die Logik und lassen Sie Ihr Verständnis – und keinen zufälligen Hack – die Lösung leiten!

