CORS in React: Was es ist, warum es wichtig ist, und wie man es aktiviert
Verständnis von CORS in React
CORS ist seit langem eine Quelle der Verwirrung – und Frustration – für Entwickler:innen, besonders für Einsteiger:innen. Das Konzept ist oft schwer zu verstehen, insbesondere wenn man Single-Page-Applications (SPAs) mit Frameworks wie React, Angular oder Vue entwickelt und dabei auf externe APIs zugreifen möchte.
In diesem Leitfaden erkläre ich CORS von Grund auf. Wir bauen gemeinsam eine einfache React-App und einen Express-Server, um zu demonstrieren, was CORS-Fehler auslöst und warum sie auftreten. Wichtiger noch: Ich zeige dir verschiedene Lösungen – allgemein und speziell für React-Umgebungen.
Was ist CORS?
CORS, oder Cross-Origin Resource Sharing, ist ein Protokoll, das festlegt, wie Webanwendungen Ressourcen von Servern mit unterschiedlichen Ursprüngen (Origins) anfordern dürfen. So wie HTTPS die Regeln für sichere Kommunikation festlegt, definiert CORS die Regeln für Cross-Origin-Anfragen.
Moderne Webapps bestehen meist aus zwei Teilen: dem Client (Frontend im Browser) und dem Server (meist ein API- oder Backend-Service). Der Client stellt Anfragen an den Server – etwa um Daten abzurufen – und der Server liefert die Antwort zurück. Kommen diese beiden Teile von unterschiedlichen Domains, Ports oder Protokollen, greift CORS.

Warum diese Architektur so häufig ist
Diese entkoppelte Architektur, bei der Frontend und Backend als eigenständige Anwendungen entwickelt und bereitgestellt werden, ist heute Standard. Ihr großer Vorteil: Flexibilität – dein Backend kann verschiedene Clients bedienen, z.B. Web-Apps, Desktop-Anwendungen, Mobile Apps oder IoT-Geräte. Jeder Client kann dieselben APIs konsumieren, ohne an die Darstellungsschicht gebunden zu sein.
Same-Origin-Policy und Cross-Origin-Anfragen
Da Client und Server getrennte Anwendungen sind, werden sie normalerweise auf unterschiedlichen Domains, Ports oder Protokollen gehostet. Das bedeutet: Selbst wenn dein eigenes Frontend mit deinem eigenen Backend spricht, sieht der Browser die Anfrage als Cross-Origin an.
Das ist noch häufiger der Fall, wenn du mit Drittanbieterdiensten arbeitest – z.B. für Authentifizierung, Analytics, Bezahldienste usw. In all diesen Fällen muss dein Frontend HTTP-Anfragen an einen anderen Ursprung senden.
Der Haken: Moderne Browser erzwingen eine Sicherheitsrichtlinie namens Same-Origin Policy, die einschränkt, wie Skripte auf Ressourcen von anderen Ursprüngen zugreifen können. CORS ist das Mechanismus, der Cross-Origin-Anfragen trotzdem unter bestimmten Bedingungen ermöglicht.

Warum Browser Cross-Origin-Anfragen blockieren
Wenn deine Webanwendung eine Ressource von einem anderen Ursprung anfordert (andere Domain, Port oder Protokoll), erzwingt der Browser die Same-Origin Policy (SOP). Diese Richtlinie soll verhindern, dass potenziell bösartige Webseiten ohne Erlaubnis auf sensible Daten von anderen Ursprüngen zugreifen können.
Das macht das Web viel sicherer: Ein Skript auf xyz.com
kann so nicht unbemerkt Daten von abcbank.com
abgreifen. Die SOP blockiert aber auch viele legitime Anwendungsfälle – zum Beispiel, wenn deine React-App auf localhost:3000
Daten von einer API auf localhost:8080
abruft.
Hier kommt CORS ins Spiel: Die Lösung für SOP-Einschränkungen
Jetzt kommt CORS (Cross-Origin Resource Sharing) ins Spiel.
CORS ist ein Protokoll, das die Same-Origin Policy gezielt aufweicht. Es erlaubt Servern, mittels bestimmter HTTP-Header anzugeben, dass bestimmte Cross-Origin-Anfragen erlaubt sind.
Macht deine Client-App also eine Anfrage an einen anderen Ursprung, kann der Server mit CORS-Headern antworten. Diese Header sind wie ein "Erlaubnisschein" für den Browser: „Diese Cross-Origin-Anfrage ist okay.“ Dein Browser blockiert die Antwort dann nicht mehr und die Ressource wird erfolgreich geteilt.

Was passiert, wenn CORS aktiviert ist?
Stellt dein Browser fest, dass die Antwort vom Server CORS-Header enthält, gibt er die Daten für deine App frei – auch wenn der Ursprung unterschiedlich ist. Das ist der Kern von CORS: kontrollierter Zugriff auf Ressourcen über Ursprung-Grenzen hinweg.
Jetzt, wo du weißt, was CORS ist und warum es gebraucht wird, schauen wir uns ein Praxisbeispiel an. Wenn du noch tiefer einsteigen willst, findest du hier einen detaillierten CORS-Guide.
🛠️ Schritt 1: Express-Server mit API-Endpunkten erstellen
Um CORS zu demonstrieren, brauchen wir:
- Einen Client (gebaut mit React), der HTTP-Anfragen macht
- Einen Server (gebaut mit Express), der API-Endpunkte bereitstellt
⚠️ Um eine echte CORS-Situation zu erzeugen, müssen Client und Server auf unterschiedlichen Ursprüngen laufen – z.B. verschiedene Ports wie localhost:3000
und localhost:8080
.
🧱 Server einrichten
Starten wir mit einem einfachen Express-Server.
- Projektordner anlegen:
mkdir cors-server && cd cors-server
- Neues Node.js-Projekt initialisieren:
npm init -y
Das erstellt eine package.json
mit Standardwerten.
- Express installieren:
npm install express
- App-Einstiegsdatei erstellen:
Lege eine Datei app.js
an und füge folgendes hinzu:
const express = require('express');
const app = express();
app.get('/', (req, res) => {
res.send('Welcome to CORS server 😁');
});
app.get('/cors', (req, res) => {
res.send('This has CORS enabled 🎈');
});
app.listen(8080, () => {
console.log('Listening on port 8080');
});
Das ist ein minimalistischer Express-Server mit zwei Endpunkten:
/
gibt eine Willkommensnachricht zurück./cors
simuliert einen Resource-Endpunkt für deine React-App.
- Server starten:
node app
Im Browser solltest du unter http://localhost:8080/ sehen:
Welcome to CORS server 😁
Und unter http://localhost:8080/cors so etwas wie:

⚛️ Schritt 2: React-App aufsetzen
Jetzt, da der Express-Server läuft, bauen wir eine React-App, die HTTP-Anfragen an den Server stellt – und absichtlich einen CORS-Fehler provoziert, um zu lernen, wie wir ihn beheben.
📦 Neues React-Projekt anlegen
In einem anderen Ordner als dein Server:
npx create-react-app react-cors-guide
Wechsle ins Projektverzeichnis und öffne die Datei src/App.js
. Ersetze ihren Inhalt mit folgendem Code:
import { useEffect } from 'react';
import './App.css';
function App() {
const makeAPICall = async () => {
try {
const response = await fetch('http://localhost:8080/', { mode: 'cors' });
const data = await response.json();
console.log({ data });
} catch (error) {
console.error('CORS error:', error);
}
};
useEffect(() => {
makeAPICall();
}, []);
return (
<div className="App">
<h1>React CORS Guide</h1>
</div>
);
}
export default App;
🧠 Was passiert hier?
- Die Funktion
makeAPICall
macht eineGET
-Anfrage anhttp://localhost:8080/
per Fetch API. { mode: 'cors' }
gibt explizit an, dass dies eine Cross-Origin-Anfrage ist.- Der
useEffect
-Hook löst die Anfrage direkt beim Mounten des<App />
-Components aus.
🔥 Erwarte einen CORS-Fehler
Starte die React-App mit:
npm start
In der Browser-Konsole erscheint wahrscheinlich ein CORS-Fehler wie:
Access to fetch at 'http://localhost:8080/' from origin 'http://localhost:3000' has been blocked by CORS policy.
Das ist die Same-Origin-Policy des Browsers in Aktion.

Verständnis des CORS-Fehlers
Der Fehler in der Browser-Konsole ist ein klassisches CORS-Problem. Obwohl beide (Client und Server) auf localhost
laufen, sind sie wegen unterschiedlicher Ports (3000
vs. 8080
) für den Browser verschiedene Ursprünge – und die SOP blockiert die Anfrage aus Sicherheitsgründen.
⚠️ Typische CORS-Fehlermeldung
Access to fetch at 'http://localhost:8080/' from origin 'http://localhost:3000'
has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is
present on the requested resource. If an opaque response serves your needs,
set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
Das bedeutet:
- Der Browser blockiert die Antwort, weil der
Access-Control-Allow-Origin
-Header in der Server-Antwort fehlt. - Es wird eine "Lösung" vorgeschlagen:
'no-cors'
zu verwenden – aber dann bekommst du nur eine undurchsichtige (opaque) Antwort, mit der du nichts anfangen kannst. - Wichtig: Dein Client ist nicht schuld. CORS ist kein Client-Fehler – es ist eine browserseitige Regel, die sich nach der Serverantwort richtet.
✅ CORS muss immer auf dem Server gelöst werden
Da die Antwort des Servers entscheidet, ob der Browser Zugriff gewährt, ist die richtige Lösung, den Server so zu konfigurieren, dass er die passenden CORS-Header sendet.
Du kannst während der Entwicklung per Proxy am Client vorbei arbeiten – aber die saubere, produktionssichere Methode ist, CORS direkt am Server zu aktivieren.
🔧 CORS auf dem Express-Server aktivieren
Zurück zu app.js
– passe den /cors
-Endpunkt an:
app.get('/cors', (req, res) => {
res.set('Access-Control-Allow-Origin', '*');
res.send({ msg: 'This has CORS enabled 🎈' });
});
Was passiert hier?
- Der
Access-Control-Allow-Origin
-Header wird auf*
gesetzt – jeder Ursprung darf auf diese Ressource zugreifen. - Das ist eine schnelle Lösung zum Testen (in Produktion solltest du Zugriffe einschränken).
🔁 React-Client aktualisieren
Stelle im Fetch-Aufruf die URL auf den neuen Endpunkt um:
const response = await fetch('http://localhost:8080/cors', { mode: 'cors' });
Speichern, ggf. die React-App neu starten.
🧪 Testen
App im Browser neu laden. Jetzt sollte die Antwort durchgehen und du siehst in der Konsole:
{ data: { msg: 'This has CORS enabled 🎈' } }
Erfolg! Du hast deine erste Cross-Origin-Anfrage mit korrekt konfiguriertem CORS gemacht.

CORS funktioniert!
Ist der CORS-Header korrekt gesetzt, verschwindet der Fehler und deine React-App empfängt die JSON-Antwort wie erwartet. 🎉 Denk daran, den Backend-Server nach Änderungen ggf. neu zu starten.
🎯 CORS auf bestimmte Ursprünge beschränken
Statt *
kannst du CORS auch auf eine bestimmte Domain beschränken, z.B. auf den React-Dev-Server:
app.get('/cors', (req, res) => {
res.set('Access-Control-Allow-Origin', 'http://localhost:3000');
res.send({ msg: 'This has CORS enabled 🎈' });
});
Empfohlen für Produktion, damit nur autorisierte Websites Zugriff auf deine API haben.
⚠️ Wenn du den Server nicht anpassen kannst
Oft ist das Aktivieren von CORS am Server nicht möglich – z.B. bei Drittanbieter-APIs (Authentifizierung, E-Mail-Versand, usw.). Dann hast du scheinbar keine Chance – oder?
🧞♂️ Workaround: Proxy in React
Ein cleverer Workaround für die Entwicklung: Proxy deine API-Requests über den Dev-Server von React.
Stell es dir vor wie ein:e Stellvertreter:in: Deine App "tut so", als käme die Anfrage von einem anderen Ursprung – und umgeht so die SOP des Browsers.
✏️ Proxy einrichten
- Öffne die
package.json
im Root deines React-Projekts. - Füge folgendes Feld hinzu:
{
...
"proxy": "http://localhost:8080"
}
- Starte den Dev-Server neu (
npm start
), und alle Requests werden jetzt über das Backend geleitet.
Wenn du jetzt z.B. mit fetch('/cors')
Daten abfragst, wird dies im Hintergrund zu http://localhost:8080/cors
weitergeleitet – für den Browser sieht es wie eine Same-Origin-Anfrage aus.
🧪 Drittanbieter-Service nutzen?
Kein Problem! Du kannst auch zu einer externen Domain proxyen:
{
...
"proxy": "https://randomservice.com"
}
Dabei beachten:
- Nur Nicht-HTML (also meist API-)Requests werden geproxyt.
- Der
Accept
-Header darf nichttext/html
sein. - Für komplexere Setups (z.B. mehrere Proxys) empfiehlt sich http-proxy-middleware.
🧹 Fazit: Best Practices für CORS in React
Für CORS gilt:
- Löse CORS immer am Server – das ist am sichersten und zuverlässigsten.
- Für die Entwicklung hilft der React-Proxy, ohne dass der Server angepasst werden muss.
- Hast du keinen Zugriff auf den API-Server, sprich den Anbieter an – oder betreibe einen eigenen Proxy.
- Tools wie CORS Unblock-Chrome-Erweiterungen funktionieren nur temporär und sollten nie in Produktion eingesetzt werden.
- Setze in fetch-Anfragen immer
{ mode: 'cors' }
, um das Verhalten explizit zu machen. - Verlasse dich nicht auf Browser-Workarounds – plane frühzeitig für die Produktion.