Der Fehler„Der Zugriff auf den Abruf bei ‚…‘ vom Ursprung ‚…‘ wurde durch die CORS-Richtlinie blockiert: Es ist kein ‚Access-Control-Allow-Origin‘-Header vorhanden“ ist einer der häufigsten Webentwicklungsfehler. Es wird vom Browser als Sicherheitsmechanismus erzwungen. Hier finden Sie alle Ursachen und Lösungen.
📋 Table of Contents
- Warum CORS existiert (erforderliche Kenntnisse)
- Fix 1: Express.js – Verwenden des cors-Pakets
- Fix 2: Manuelle CORS-Header in Express
- Fix 3: Nginx Reverse Proxy
- Fix 4: Frontend – Anmeldeinformationsmodus
- Preflight-Anfragen verstehen
- Entwicklungsproxy (CORS während der Entwicklung vermeiden)
- Häufige Fehler
- Häufig gestellte Fragen
- Fazit
Warum CORS existiert (erforderliche Kenntnisse)
CORS (Cross-Origin Resource Sharing) verhindert, dass bösartige Websites mithilfe Ihrer angemeldeten Cookies Anfragen an die API Ihrer Bank stellen. Ohne CORS könnte der Besuch von evil.com mit Ihren Sitzungscookies stillschweigend API-Aufrufe an yourbank.com durchführen. Der Browser erzwingt CORS – Server geben an, welche Ursprünge zulässig sind.
CORS ist eine Browser-Sicherheitsfunktion – Dies gilt nur für vom Browser initiierte Anfragen. Curl-, Postman- und Server-zu-Server-Anfragen sind von CORS nicht betroffen.
Fix 1: Express.js – Verwenden des cors-Pakets
npm install cors
const express = require('express');
const cors = require('cors');
const app = express();
// ✅ Allow specific origin (recommended for production)
app.use(cors({
origin: 'https://yourfrontend.com',
methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
allowedHeaders: ['Content-Type', 'Authorization'],
credentials: true, // required if frontend sends cookies/auth headers
}));
// ✅ Allow multiple origins
const allowedOrigins = ['https://app.example.com', 'https://admin.example.com'];
app.use(cors({
origin: (origin, callback) => {
if (!origin || allowedOrigins.includes(origin)) {
callback(null, true);
} else {
callback(new Error(`Origin ${origin} not allowed by CORS`));
}
},
credentials: true,
}));
// ❌ Allow all origins (never in production with credentials)
app.use(cors({ origin: '*' }));
// Note: wildcard '*' cannot be used with credentials: true
Fix 2: Manuelle CORS-Header in Express
// Without the cors package
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', 'https://yourfrontend.com');
res.header('Access-Control-Allow-Methods', 'GET,POST,PUT,DELETE,OPTIONS');
res.header('Access-Control-Allow-Headers', 'Content-Type,Authorization');
res.header('Access-Control-Allow-Credentials', 'true');
// Handle preflight requests
if (req.method === 'OPTIONS') {
return res.status(204).end();
}
next();
});
Fix 3: Nginx Reverse Proxy
location /api/ {
proxy_pass http://localhost:3000/;
# CORS headers
add_header 'Access-Control-Allow-Origin' 'https://yourfrontend.com' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization' always;
add_header 'Access-Control-Allow-Credentials' 'true' always;
# Handle preflight
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' 'https://yourfrontend.com';
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain charset=UTF-8';
add_header 'Content-Length' 0;
return 204;
}
}
Fix 4: Frontend – Anmeldeinformationsmodus
// ❌ Fetch without credentials — cookies not sent
const res = await fetch('https://api.example.com/user');
// ✅ Include credentials (cookies, authorization headers)
const res = await fetch('https://api.example.com/user', {
credentials: 'include', // send cookies cross-origin
});
// For axios:
axios.defaults.withCredentials = true;
// Or per-request:
axios.get('/api/user', { withCredentials: true });
Wichtig: Wenncredentials: 'include', muss der ServerAccess-Control-Allow-Originfestlegen zum spezifischen Ursprung (nicht*) UNDAccess-Control-Allow-Credentials: true.
Preflight-Anfragen verstehen
Bei „nicht einfachen“ Anfragen (PUT, DELETE, benutzerdefinierte Header, Anwendungs-/JSON-Body) sendet der Browser zunächst eine OPTIONS-Preflight-Anfrage, um zu prüfen, ob die tatsächliche Anfrage zulässig ist. Wenn der Preflight fehlschlägt, wird die eigentliche Anforderung nie ausgeführt.
// Browser sends OPTIONS before POST with JSON body:
OPTIONS /api/users HTTP/1.1
Origin: https://frontend.com
Access-Control-Request-Method: POST
Access-Control-Request-Headers: Content-Type
// Server must respond:
HTTP/1.1 204 No Content
Access-Control-Allow-Origin: https://frontend.com
Access-Control-Allow-Methods: POST
Access-Control-Allow-Headers: Content-Type
Access-Control-Max-Age: 86400 // cache preflight for 24 hours
Entwicklungsproxy (CORS während der Entwicklung vermeiden)
// vite.config.ts — proxy /api to backend during dev
export default {
server: {
proxy: {
'/api': {
target: 'http://localhost:3000',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, ''),
}
}
}
};
// package.json (Create React App) — proxy all /api requests
{
"proxy": "http://localhost:3000"
}
Der Proxy stellt Anfragen vom gleichen Ursprung wie das Frontend (vom Entwicklungsserver) und umgeht CORS während der Entwicklung vollständig – ohne die Produktionssicherheit zu beeinträchtigen.
Häufige Fehler
// ❌ Mistake 1: CORS headers on wrong route
app.get('/api/data', (req, res) => {
res.header('Access-Control-Allow-Origin', '*');
res.json(data);
});
// OPTIONS preflight hits a different handler that doesn't have CORS headers
// ❌ Mistake 2: Setting headers after response sent
app.use(cors());
app.get('/data', authenticate, (req, res) => {
res.header('Access-Control-Allow-Origin', '*'); // Too late if cors() runs first
});
// ❌ Mistake 3: Multiple conflicting CORS headers
// Browser rejects when two Access-Control-Allow-Origin headers present
// Don't set CORS in both nginx AND Express — pick one place
Häufig gestellte Fragen
F: Kann ich CORS im Browser für die Entwicklung deaktivieren?
A: Ja:open -a "Google Chrome" --args --disable-web-security --user-data-dir="/tmp/chrome-dev". NUR für lokale Entwickler – durchsuchen Sie niemals echte Websites mit dieser Flagge. Die Verwendung eines Proxys ist sicherer und erfordert keine Deaktivierung der Sicherheit.
F: Warum funktioniert es in Postman, aber nicht im Browser?
A: CORS wird nur von Browsern erzwungen. Postman sendet die Anfrage direkt ohne eine Browser-CORS-Prüfung. Dies bestätigt, dass Ihr Server funktioniert – Sie müssen lediglich CORS-Header hinzufügen.
F: Sollte ich CORS-Header in der Anwendung oder im Reverse-Proxy hinzufügen?
A: Nur ein Ort. Wenn Sie Nginx verwenden, fügen Sie Header in Nginx hinzu und nicht in Express (verhindert doppelte Header). Wenn Sie einen Dienst ohne Nginx-Steuerung bereitstellen, fügen Sie Express hinzu.
F: Warum funktioniert meine API vom gleichen Ursprung aus, aber nicht ursprungsübergreifend?
A: Genau das verhindert CORS – Cross-Origin-Anfragen erfordern eine explizite Serverberechtigung. Anfragen mit demselben Ursprung (Frontend und API auf derselben Domäne/einem Port) benötigen keine CORS-Header.
F: Kann ich einen CORS-Proxy-Dienst verwenden?
A: Für die Entwicklung von Prototypen funktionieren Dienste wie cors-anywhere. Nie für die Produktion – Sie senden alle Ihre API-Anfragen über einen Drittanbieterdienst. Korrigieren Sie CORS ordnungsgemäß auf Ihrem Server.
Fazit
Korrigieren Sie CORS, indem Sie das richtigeAccess-Control-Allow-Originhinzufügen Header auf Ihrem Server – nicht durch die Deaktivierung von CORS oder die Verwendung von Browser-Plugins. Für Express.js ist dascors Das npm-Paket behandelt alle Fälle sauber. Fügen Sie für Nginx Header auf Proxy-Ebene hinzu. Verwenden Sie für die Entwicklung die Proxy-Konfiguration von Vite, um CORS vollständig zu vermeiden. Geben Sie immer genaue Ursprünge an und nicht den Platzhalter* in der Produktion, insbesondere bei der Verwendung von Anmeldeinformationen.
🔗 Share this article
✍️ Leave a Comment