Einleitung: Wenn der Browser "Nein" sagt, aber Postman "Ja"
Stellen Sie sich folgende Situation vor: Sie schreiben ein Frontend in JavaScript und führen eine fetch-Anfrage an eine API aus. Als Antwort erhalten Sie einen roten Fehler in der Konsole:
Access to fetch at 'https://api.example.com/data' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.Sie fassen sich an den Kopf, öffnen Postman, fügen dieselbe URL ein, klicken auf Senden – und siehe da, die Daten kommen an! Der Server funktioniert also? Er funktioniert. Warum blockiert der Browser dann die Anfrage?
Diese Situation ist ein Klassiker der Webentwicklung. Auf Stack Overflow hat diese Frage tausende Aufrufe gesammelt. Heute schauen wir unter die Haube und verstehen, warum das passiert, wie CORS funktioniert und wie man es behebt. Los geht's!
Was ist CORS und wozu braucht man es?
CORS (Cross-Origin Resource Sharing) ist ein Sicherheitsmechanismus des Browsers. Er verbietet JavaScript von einer Website (z.B. http://localhost:3000), Anfragen an eine andere (z.B. https://api.example.com) zu stellen, es sei denn, der Server erlaubt dies ausdrücklich.
Warum? Damit ein Angreifer nicht über Ihren Browser Daten von einer anderen Website stehlen kann. Ohne CORS könnte jedes Skript Ihre E-Mails, Bankkonten lesen – ein Albtraum.
Allerdings gibt es einen Haken: CORS funktioniert nur im Browser. Postman, curl, serverseitige Anfragen (Node.js, Python) – sie prüfen CORS nicht. Das ist der erste und wichtigste Grund, warum Postman funktioniert, JavaScript aber nicht.
Wie funktioniert CORS unter der Haube: Einfach erklärt
Wenn Ihr JavaScript (z.B. fetch) eine Cross-Origin-Anfrage stellt, macht der Browser zwei Dinge:
- Er prüft den Anfragetyp.
- Wenn nötig – sendet er eine Preflight-Anfrage (OPTIONS).
Einfache Anfrage vs. Preflight
Es gibt zwei Arten von Cross-Origin-Anfragen:
- Einfache Anfrage – wenn Sie GET, POST oder HEAD verwenden und nur Basis-Header (Content-Type: text/plain, application/x-www-form-urlencoded, multipart/form-data). Der Browser sendet die Anfrage und prüft den Antwort-Header
Access-Control-Allow-Origin. - Preflight-Anfrage – wenn Sie nicht standardmäßige Header (z.B.
Authorization), die Methoden PUT/DELETE oder Content-Type: application/json verwenden. Der Browser sendet zuerst eine OPTIONS-Anfrage, um zu fragen: "Darf ich so eine Anfrage stellen?"
Hier ist ein Beispiel für Preflight im Code:
fetch('https://api.example.com/data', { method: 'POST', headers: { 'Content-Type': 'application/json', // Dies löst Preflight aus 'Authorization': 'Bearer my-token' }, body: JSON.stringify({ key: 'value' })}).then(response => response.json()).then(data => console.log(data)).catch(err => console.error('CORS error:', err));Wenn der Server nicht auf OPTIONS mit dem korrekten Header Access-Control-Allow-Origin antwortet – blockiert der Browser die Hauptanfrage.
Warum ignoriert Postman CORS?
Postman ist kein Browser. Es verwendet nicht die Same-Origin-Policy. Es sendet einfach eine HTTP-Anfrage und erhält eine Antwort. Es ist ihm egal, woher die Anfrage kommt – es prüft keine CORS-Header. Der Server kann zurückgeben, was er will, Postman zeigt die Antwort an.
Wenn Sie also eine API über Postman testen, sehen Sie, dass der Server funktioniert. Aber der Browser verlangt, dass der Server den Zugriff von Ihrer Domain ausdrücklich erlaubt.
Wie behebt man den CORS-Fehler: 3 praktische Methoden
1. Server konfigurieren (der richtige Weg)
Wenn Sie Zugriff auf den Server haben, fügen Sie den Header Access-Control-Allow-Origin hinzu. Zum Beispiel auf Node.js mit Express:
const express = require('express');const app = ex