---
title: "CORS-Fehler beheben: Was „blocked by CORS policy“ bedeutet"
description: "Bei einem CORS-Fehler lässt der Browser Ihre Seite die Antwort eines anderen Origins nicht lesen. Was „blocked by CORS policy“ heißt und wie Sie es beheben."
url: https://proxynet.io/de/blog/cors-error
date: 2026-10-06
author: "Acar Diveroli"
category: "Anleitungen, Web Scraping"
lang: de
---

# CORS-Fehler beheben: Was „blocked by CORS policy“ bedeutet

Ihr Frontend läuft unter `http://localhost:5173`, Ihre API unter `http://localhost:3001`. In curl und Postman liefert die API JSON, im Browser aber wirft `fetch()` den Fehler `TypeError: Failed to fetch`, und die Konsole zeigt: `Access to fetch at 'http://localhost:3001/api/products' from origin 'http://localhost:5173' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.` Dabei zeigt das Log der API, dass die Anfrage angekommen ist und mit `200` beantwortet wurde.

Im Folgenden: was ein Origin ist, warum der Browser die Antwort blockiert, einfache Anfragen im Vergleich zu Preflight-Anfragen, jede Chrome-Meldung, getestete Lösungen für Express, Flask und Vite, ein Weg über das Backend für APIs, die Ihnen nicht gehören, und warum Scraping-Code nie auf CORS stößt.

> **Hinweis: Kurzantwort**
>
> Ein CORS-Fehler bedeutet, dass der Browser eine Antwort von einem anderen Origin erhalten hat, sie aber nicht an Ihr JavaScript übergibt, weil der Server keinen `Access-Control-Allow-Origin`-Header mit dem Origin Ihrer Seite geschickt hat. Ein Origin besteht aus Schema, Host und Port zusammen, deshalb sind `localhost:5173` und `localhost:3001` verschiedene Origins. Beheben Sie den Fehler auf dem Server: Erlauben Sie genau Ihren Origin, beantworten Sie `OPTIONS`-Preflight-Anfragen, und führen Sie die Methoden und Header auf, die Sie verwenden. In der Entwicklung bringt ein Dev-Server-Proxy die API auf denselben Origin; eine API, die Ihnen nicht gehört, rufen Sie aus Ihrem Backend auf. `mode: "no-cors"`, Browsererweiterungen, öffentliche CORS-Proxys, VPNs und Proxys beheben ihn nicht.

## Was ist ein CORS-Fehler?

Es ist der Browser, der sich weigert, Ihrem Skript eine Antwort zu übergeben. CORS, Cross-Origin Resource Sharing, ist ein Satz von HTTP-Antwort-Headern, mit denen ein Server dem Browser mitteilt, welche anderen Origins seine Antworten lesen dürfen. Der [Fetch Standard](https://fetch.spec.whatwg.org/#http-cors-protocol) legt das als Opt-in an, damit Daten hinter einer Firewall oder einem Login nicht von vornherein an andere Websites gelangen. Fehlen passende Header, greift die Standardregel des Browsers, die Same-Origin-Policy, und der Browser blockiert das Lesen. Die „CORS policy“ aus der Fehlermeldung meint genau diese Regeln.

Daraus folgen drei Dinge. Die Logs des Servers sehen normal aus, weil der Browser den Fehler erzeugt hat. Ihr Code bekommt nur einen allgemeinen Fehler, `TypeError: Failed to fetch` von `fetch()` oder `AxiosError: Network Error` (Code `ERR_NETWORK`) von Axios, und der Grund steht nur in der Konsole. Und die Lösung gehört auf den Server, der antwortet, nicht in den Code, der fragt.

## Was ist ein Origin, und was blockiert die Same-Origin-Policy?

Ein Origin (Ursprung) besteht aus Schema, Host und Port einer URL. Zwei URLs haben nur dann denselben Origin, wenn alle drei übereinstimmen:

- `http://localhost:5173` und `http://localhost:3001`: verschiedene Ports, verschiedene Origins.
- `http://example.com` und `https://example.com`: verschiedene Schemas.
- `https://example.com` und `https://api.example.com`: verschiedene Hosts; eine Subdomain ist ein eigener Origin.
- `https://example.com/shop` und `https://example.com/api`: derselbe Origin; der Pfad zählt nicht.

Die Same-Origin-Policy erlaubt einer Seite weiterhin, Bilder, Skripte und Stylesheets von anderen Websites einzubinden, auf sie zu verlinken und Formulare an sie zu senden. Was sie unterbindet, ist das Lesen: Ein Skript kann eine Antwort von einem anderen Origin nicht lesen, solange dieser Origin es nicht erlaubt ([MDN: Same-origin policy](https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy)). CORS ist der Weg, auf dem der Server diese Erlaubnis erteilt.

## Wie läuft eine Cross-Origin-Anfrage Schritt für Schritt ab?

1. Ihre Seite auf Origin A ruft `fetch()` für eine URL auf Origin B auf.
2. Der Browser prüft, ob die Anfrage „einfach“ ist. Wenn nicht, schickt er zuerst einen Preflight (nächster Abschnitt).
3. Er fügt einen `Origin`-Header hinzu, etwa `Origin: http://localhost:5173`. Skripte können ihn weder setzen noch entfernen.
4. Der Server führt seinen Code aus und antwortet. Was der Code getan hat, ist damit bereits geschehen.
5. Der Browser vergleicht den `Access-Control-Allow-Origin` der Antwort mit dem Origin der Seite. Er akzeptiert eine exakte Übereinstimmung oder `*`, wenn keine Zugangsdaten wie Cookies mitgeschickt wurden.
6. Bei Übereinstimmung erhält Ihr Code die Antwort; andernfalls verwirft der Browser sie, das Promise wird abgelehnt, und die Konsole nennt den Grund.

Schritt 4 übersehen viele: CORS hält Anfragen nicht vom Server fern, und curl, Skripte und andere Server lassen Schritt 5 ganz aus. CORS schützt Besucher, damit eine Seite, die sie öffnen, nicht mit ihren Cookies ihre Daten auf anderen Websites lesen kann; Ihre API schützt es nicht.

## Einfache Anfragen und Preflight: Warum GET funktioniert, POST aber nicht

Eine Anfrage ist „einfach“, wenn sie `GET`, `HEAD` oder `POST` verwendet und nur Header von der Safelist enthält: `Accept`, `Accept-Language`, `Content-Language`, `Range` sowie `Content-Type` mit `application/x-www-form-urlencoded`, `multipart/form-data` oder `text/plain`. Alles andere bekommt einen Preflight: eine `OPTIONS`-Anfrage mit `Access-Control-Request-Method` und `Access-Control-Request-Headers`, nach der der Browser die eigentliche Anfrage nur sendet, wenn die Antwort sie erlaubt ([MDN: CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CORS)). Ein JSON-Body, ein `Authorization`-Header, `PUT`, `PATCH`, `DELETE` oder ein eigener Header wie `X-Request-ID` lösen einen Preflight aus.

Wir haben von einer Seite auf Port 5173 ein einfaches `GET` und ein `POST` mit JSON-Body an eine API auf Port 3001 geschickt, die keine CORS-Header sendet. Die API protokollierte:

```text
[no-cors-api] GET /api/products origin=http://localhost:5173
[no-cors-api] OPTIONS /api/products origin=http://localhost:5173
```

Das `GET` wurde mit `200` und den Daten beantwortet, und der Browser blockierte es trotzdem. Vom `POST` kam nur der Preflight an; er scheiterte, also wurde das `POST` nie gesendet. Ein einfaches Cross-Origin-`POST`, etwa ein formularkodiertes, erreicht den Server dagegen und wird ausgeführt, obwohl die Seite einen Fehler sieht. Schützen Sie solche Aktionen deshalb mit Authentifizierung und CSRF-Tokens, nicht mit CORS.

Mit `Access-Control-Max-Age` darf der Browser eine Preflight-Antwort zwischenspeichern. Der Standardwert im Fetch Standard beträgt 5 Sekunden; Chromium begrenzt den Wert auf 2 Stunden, Firefox auf 24 Stunden.

## Was bedeuten die einzelnen „blocked by CORS policy“-Meldungen?

Jede Chrome-Meldung beginnt mit `Access to fetch at '<URL>' from origin '<origin>' has been blocked by CORS policy:`, bei Axios und `XMLHttpRequest` mit `Access to XMLHttpRequest at`. Chromium hinterlegt diese Texte fest auf Englisch im Quellcode, deshalb erscheinen sie auch in einem deutschsprachigen Browser auf Englisch. Der Text nach dem Doppelpunkt ist die Ursache. Die ersten fünf Zeilen der Tabelle sind in unserem Test mit einem Browser auf Basis von Chromium 152 wortgleich erschienen; die übrigen stammen aus dem Quellcode von Chromium.

| Meldung nach „blocked by CORS policy:“ | Bedeutung | Lösung |
|---|---|---|
| `No 'Access-Control-Allow-Origin' header is present on the requested resource.` | Kein CORS-Header: nicht eingerichtet, oder eine Fehlerseite hat geantwortet | Ihren Origin erlauben; den echten Status prüfen |
| `Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present…` | Die `OPTIONS`-Antwort hatte keinen CORS-Header; die eigentliche Anfrage wurde nicht gesendet | `OPTIONS` mit CORS-Headern beantworten |
| `The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'.` | Cookies gesendet, der Server antwortete mit `*` | Exakter Origin plus `Access-Control-Allow-Credentials: true` |
| `Request header field x-debug is not allowed by Access-Control-Allow-Headers in preflight response.` | Ein Header, den Sie senden, ist nicht erlaubt | Ihn erlauben oder nicht mehr senden |
| `Method PATCH is not allowed by Access-Control-Allow-Methods in preflight response.` | Die Methode ist nicht erlaubt | Die Methode ergänzen |
| `The 'Access-Control-Allow-Origin' header has a value '…' that is not equal to the supplied origin.` | Ein anderer Origin ist erlaubt: falscher Port, `http`, ein Schrägstrich am Ende | Die Freigabeliste korrigieren |
| `The 'Access-Control-Allow-Origin' header contains multiple values '…', but only one is allowed.` | Zwei Schichten setzen den Header, etwa die App und nginx | Ihn an einer einzigen Stelle setzen |
| `Response to preflight request doesn't pass access control check: It does not have HTTP ok status.` | `OPTIONS` bekam `401`, `404`, `405` oder `500` | `OPTIONS` vor der Authentifizierung durchlassen |
| `Response to preflight request doesn't pass access control check: Redirect is not allowed for a preflight request.` | `OPTIONS` wurde umgeleitet, etwa auf `https` oder eine Login-Seite | Die endgültige URL aufrufen |

Ältere Chrome-Versionen hängten einen Satz an, der `mode: 'no-cors'` vorschlug; Chromium hat ihn im März 2025 gestrichen, weil er in die Irre führte (den Grund nennen die Häufigen Fragen unten). Firefox schreibt `Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at … (Reason: CORS header 'Access-Control-Allow-Origin' missing)`.

## Wie finden Sie die eigentliche Ursache?

Öffnen Sie die Entwicklertools (F12) und lesen Sie die Zeile im Tab **Console** (in der deutschen Oberfläche **Konsole**): URL, Origin, Grund. Im Tab **Network** (deutsch **Netzwerk**) zeigt die blockierte Anfrage in der Spalte **Status** den Eintrag `CORS error` (deutsch `CORS-Fehler`), und ein Aufruf mit Preflight hat einen eigenen `OPTIONS`-Eintrag, in dessen Spalte **Initiator** `Preflight` steht. Klicken Sie den Eintrag an, um die Header zu sehen.

Der echte Statuscode geht leicht unter. In unserem Test antwortete ein Gateway mit `502` ohne CORS-Header: Die Konsole zeigte nur die Zeile „No 'Access-Control-Allow-Origin' header“, während `curl -i` auf dieselbe URL `HTTP/1.1 502 Bad Gateway` ausgab. Fehlerseiten von nginx, Load Balancern oder einer abgestürzten App tragen selten CORS-Header, deshalb sehen Ausfälle wie CORS-Probleme aus. nginx wendet `add_header` nur auf Antworten mit 200, 201, 204, 206, 301, 302, 303, 304, 307 und 308 an, sofern Sie nicht den Parameter `always` ergänzen ([nginx-Dokumentation](https://nginx.org/en/docs/http/ngx_http_headers_module.html#add_header)).

## Wie beheben Sie einen CORS-Fehler bei Ihrer eigenen API?

Senden Sie die Header von der API selbst, und zwar für die exakten Origins Ihres Frontends. Wir haben jedes Snippet am 6. Oktober 2026 mit Node.js 24.11, Express 5.2.1, cors 2.8.6, Vite 8.3.3, Python 3.13, Flask 3.1.3 und Flask-CORS 6.0.5 getestet.

### Express

Installieren Sie mit `npm install express cors`, und setzen Sie `"type": "module"` in der `package.json`.

```js
// server.js: eine API, die genau ein Frontend zulässt (Express 5, cors 2.8)
import express from "express";
import cors from "cors";

const app = express();

app.use(cors({
  origin: ["https://app.example.com", "http://localhost:5173"],
  methods: ["GET", "POST", "PUT", "DELETE"],
  allowedHeaders: ["Content-Type", "Authorization"],
  credentials: true,
  maxAge: 600,
}));
app.use(express.json());

app.get("/api/products", (req, res) => {
  res.json([{ id: 1, name: "Desk lamp" }]);
});

app.post("/api/products", (req, res) => {
  res.status(201).json({ created: req.body });
});

app.listen(3000, () => console.log("API on http://localhost:3000"));
```

Mit `app.use()` vor den Routen registriert, beantwortet die Middleware auch jeden `OPTIONS`-Preflight ([cors-Middleware von Express](https://expressjs.com/en/resources/middleware/cors.html)). Schreiben Sie die Origins genau so, wie der Browser sie sendet, ohne Schrägstrich am Ende. Andere Origins erhalten keinen `Access-Control-Allow-Origin`-Header, und genau das ist gewollt. Behalten Sie `credentials: true` nur, wenn das Frontend Cookies mit `credentials: "include"` sendet.

Prüfen Sie den Preflight im Terminal:

```bash
curl -i -X OPTIONS http://localhost:3000/api/products \
  -H "Origin: http://localhost:5173" \
  -H "Access-Control-Request-Method: POST" \
  -H "Access-Control-Request-Headers: content-type"
```

Die relevanten Zeilen aus unserem Lauf:

```text
HTTP/1.1 204 No Content
Access-Control-Allow-Origin: http://localhost:5173
Vary: Origin
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: GET,POST,PUT,DELETE
Access-Control-Allow-Headers: Content-Type,Authorization
Access-Control-Max-Age: 600
```

`Vary: Origin` sagt Caches und CDNs, dass die Antwort vom `Origin`-Header abhängt. Mit `Origin: https://evil.example` liefert derselbe Befehl `204`, aber ohne die Zeile `Access-Control-Allow-Origin`.

### Flask

Installieren Sie mit `pip install flask flask-cors`.

```python
# app.py: dieselbe API in Flask 3 mit Flask-CORS 6
from flask import Flask, jsonify, request
from flask_cors import CORS

app = Flask(__name__)
CORS(
    app,
    resources={r"/api/*": {"origins": ["https://app.example.com", "http://localhost:5173"]}},
    allow_headers=["Content-Type", "Authorization"],
    supports_credentials=True,
    max_age=600,
)

@app.get("/api/products")
def list_products():
    return jsonify([{"id": 1, "name": "Desk lamp"}])

@app.post("/api/products")
def create_product():
    return jsonify({"created": request.get_json()}), 201

if __name__ == "__main__":
    app.run(port=5000)
```

In unserem Lauf lieferte der Preflight `200` mit dem Origin, den Methoden und `Vary: Origin`, und das `POST` der Seite ergab `201`. Übergeben Sie bei `supports_credentials=True` immer eine Origin-Liste: Ohne sie hat Flask-CORS 6.0.5 uns einen beliebigen Origin, `https://evil.example`, zusammen mit `Access-Control-Allow-Credentials: true` zurückgespiegelt.

### nginx, Gateways und CDNs

Setzt ein Reverse-Proxy die Header statt der App, geben Sie jedem `add_header` den Parameter `always`, damit auch Fehlerantworten sie tragen, und lassen Sie nur eine Schicht die Header setzen. Kopieren Sie nie einen beliebigen eingehenden `Origin` in die Antwort, während Sie Credentials erlauben: Dann könnte jede Website mit den Cookies Ihrer Nutzer deren Daten lesen. Prüfen Sie Origins gegen eine feste Liste.

## Lokale Entwicklung: Der Dev-Server leitet die API weiter

In der Entwicklung ist die einfachste Lösung, die API auf denselben Origin zu bringen. Der Dev-Server von Vite kann jeden Pfad weiterleiten, der mit `/api` beginnt:

```js
// vite.config.js: in der Entwicklung geht /api über Vite an die API
import { defineConfig } from "vite";

export default defineConfig({
  server: {
    port: 5173,
    proxy: {
      "/api": {
        target: "http://localhost:3000",
        changeOrigin: true,
      },
    },
  },
});
```

Das Frontend ruft `fetch("/api/products")` ohne Host auf. Der Browser sieht seinen eigenen Origin, also findet keine CORS-Prüfung statt, und Vite reicht die Anfrage an Port 3000 weiter; in unserem Test lieferte `GET` `200` und `POST` `201`. `changeOrigin` setzt den `Host`-Header auf das Ziel. webpack-dev-server bietet dasselbe über `devServer.proxy`. In der Produktion stellen Sie Frontend und API über Ihren Webserver unter einem Origin bereit oder behalten die CORS-Einrichtung von oben.

## Wenn die API nicht Ihnen gehört: Aufruf über Ihr Backend

Eine Drittanbieter-API ohne CORS-Header ist meist für Server gedacht, oft weil ihr geheimer Schlüssel nie in einen Browser gelangen darf. Fügen Sie Ihrem Backend eine Route hinzu: Der Browser ruft Ihren Origin auf, Ihr Server ruft die API auf.

```js
// relay.js: Ihr Backend ruft die Drittanbieter-API auf; der Browser spricht nur mit Ihnen
import express from "express";

const app = express();
const PARTNER_URL = "https://api.partner.example/v1/products";

app.get("/api/partner-products", async (req, res) => {
  try {
    const r = await fetch(PARTNER_URL, {
      headers: { Authorization: `Bearer ${process.env.PARTNER_API_KEY}` },
      signal: AbortSignal.timeout(10_000),
    });
    res.status(r.status).type(r.headers.get("content-type") ?? "application/json");
    res.send(await r.text());
  } catch (err) {
    res.status(502).json({ error: "partner API unreachable", detail: err.cause?.code ?? err.name });
  }
});

app.listen(8080, () => console.log("relay on http://localhost:8080"));
```

Gegen einen lokalen Ersatz für die Partner-API ohne CORS-Header lieferte die Route das JSON mit `200`. Stellen Sie die Route vom Origin der Seite aus bereit; der Schlüssel bleibt in einer Umgebungsvariablen auf dem Server. Header, Bodys und Authentifizierung mit serverseitigem `fetch` und Axios behandelt der Beitrag [cURL in JavaScript](/de/blog/curl-in-javascript).

Halten Sie das Ziel fest. Eine Route, die abruft, was auch immer in `?url=` ankommt, macht Ihren Server zu einem offenen Proxy, den jeder nutzen kann, auch gegen interne Adressen, die nur Ihr Server erreicht. Die Nutzungsbedingungen und Rate Limits der API gelten weiter: Der Aufruf ist umgezogen, die Regeln nicht.

## Warum öffentliche CORS-Proxys ein Risiko sind

Ein öffentlicher CORS-Proxy ruft eine URL für Sie ab und hängt `Access-Control-Allow-Origin: *` an die Antwort. Der Fehler verschwindet, aber:

- Der Betreiber sieht die vollständige URL, jeden Header einschließlich API-Schlüsseln und Tokens sowie die Antwort.
- Er kann die Antwort verändern, und Ihre Seite vertraut ihr.
- Die Anfragen Ihrer Nutzer laufen über ein Unternehmen, mit dem Sie keine Vereinbarung haben.
- Seine Rate Limits und Ausfälle werden zu Ihren.

## CORS und Web Scraping: Warum Ihr Python- oder Node.js-Skript den Fehler nie sieht

CORS gibt es nur in Browsern. Wir haben dieselbe API, die der Browser blockiert hatte, diesmal aus Node.js 24 abgefragt:

```js
// Dieselbe Anfrage aus Node.js: kein Browser, keine CORS-Prüfung
const r = await fetch("http://localhost:3001/api/products");
console.log(r.status, r.headers.get("access-control-allow-origin"), await r.text());
```

```text
200 null [{"id":1,"name":"Desk lamp"}]
```

Kein `Access-Control-Allow-Origin`-Header, und Node.js liest die Antwort trotzdem; Requests in Python und curl verhalten sich genauso. Wenn Sie versuchen, mit `fetch()` in der Browserkonsole oder in einer Frontend-App Daten zu sammeln, sagt Ihnen der CORS-Fehler, dass die Aufgabe in serverseitigen Code gehört. Welche Sprache dafür passt, vergleicht [Web Scraping: JavaScript oder Python?](/de/blog/web-scraping-javascript-vs-python). Auch dort gelten die Regeln der Website: Halten Sie sich an `robots.txt`, halten Sie die Anfragerate niedrig, und nutzen Sie die offizielle API, wenn es eine gibt.

Ein Proxy behebt keinen CORS-Fehler. Der Browser vergleicht den Origin der Seite mit dem `Access-Control-Allow-Origin`-Header, und die IP-Adresse ist nicht Teil dieser Prüfung; ein Residential-Proxy, ein Datacenter-Proxy oder ein VPN ändert also nichts. Proxys gehören in den HTTP-Client Ihres serverseitigen Codes, wie in [Proxys in Node.js verwenden](/de/blog/nodejs-proxy) gezeigt.

Für erlaubte Datenerhebung, die lokale Ergebnisse aus vielen Ländern und Städten braucht, schickt ein [Residential-Proxy](https://proxynet.io/de/residential-proxy) die Anfragen über private Internetanschlüsse, mit Targeting nach Land und Stadt.

Für große Mengen an Anfragen an öffentliche APIs und schwach geschützte Seiten bietet ein [Datacenter-Proxy](https://proxynet.io/de/datacenter-proxy) dedizierte IPv4-Adressen mit Traffic ohne Kontingent.

## Wer stößt auf CORS-Fehler?

- Frontend-Entwickler, deren App und API auf verschiedenen Ports laufen.
- Single-Page-Apps, die eine Drittanbieter-API direkt aus dem Browser aufrufen.
- Teams, die eine API auf eine Subdomain wie `api.example.com` oder auf `https` umziehen.
- KI-generierte Frontends, die eine API direkt aufrufen, manchmal mit dem Schlüssel in der Seite.

## Häufige Fehler

- **`Access-Control-Allow-Origin` in die Anfrage schreiben.** Das ist ein Antwort-Header; in `fetch()` wird er zu einem eigenen Header, der einen Preflight auslöst.
- **`mode: "no-cors"` verwenden.** Die Antwort kommt undurchsichtig (opaque) zurück: Status `0`, der Body ist nicht lesbar.
- **Eine „Allow CORS“-Erweiterung oder abgeschaltete Web-Sicherheit.** Das ändert nur Ihren eigenen Browser, und eine solche Erweiterung kann die Seiten lesen, auf denen sie läuft.
- **Mit `*` antworten, während das Frontend Cookies sendet.** Der Browser lehnt diese Kombination ab.
- **`app.options("*", cors())` in Express 5.** Die App bricht beim Start mit `PathError [TypeError]: Missing parameter name at index 1: *` ab; `app.use(cors())` beantwortet Preflights bereits.
- **Authentifizierungs-Middleware, die `OPTIONS` ablehnt.** Preflights tragen kein Token und scheitern deshalb mit „It does not have HTTP ok status“.

## Entscheidungshilfe

| Situation | Was zu tun ist |
|---|---|
| Frontend und API laufen in der Entwicklung auf verschiedenen Ports | Dev-Server-Proxy (`server.proxy` in Vite) |
| Ihre API, aufgerufen von Ihrem Frontend | Die exakten Origins erlauben; `OPTIONS` beantworten |
| Das Frontend sendet Cookies | Exakter Origin, `Access-Control-Allow-Credentials: true`, `Vary: Origin` |
| Ein Header oder eine Methode „is not allowed“ | In `Access-Control-Allow-Headers` bzw. `-Methods` ergänzen |
| Der Fehler tritt nach einem Deployment oder unter Last auf | Den echten Status mit curl prüfen; `always` in nginx |
| Eine Drittanbieter-API ohne CORS-Header | Aus Ihrem Backend aufrufen, Schlüssel auf dem Server |
| Daten von anderen Websites sammeln | Serverseitiger Code; dort gilt CORS nicht |

## Häufige Fragen

### Warum funktionieren Postman und curl, während der Browser einen CORS-Fehler zeigt?

Nur Browser setzen CORS durch. Der Server schickt jedem Client dieselbe Antwort, und nur der Browser prüft `Access-Control-Allow-Origin`, bevor er sie an ein Skript übergibt. Ein funktionierender curl-Aufruf beweist, dass die API läuft, nicht, dass ein Browser die Antwort lesen darf.

### Warum bekomme ich auf localhost einen CORS-Fehler?

Ein anderer Port ist ein anderer Origin: `localhost:5173` und `localhost:3000` sind zwei Origins auf einem Rechner. Erlauben Sie den Origin des Frontends in der API, oder nutzen Sie den Dev-Server-Proxy. Unabhängig davon braucht seit Chrome 142 eine öffentliche Website, die `localhost` oder ein Gerät in Ihrem Heimnetz aufruft, Ihre Erlaubnis; lehnen Sie ab, meldet die Konsole einen verweigerten Adressraum `loopback` oder `local`.

### Behebt mode: "no-cors" einen CORS-Fehler?

Nein. Die Anfrage wird gesendet, aber der Browser liefert eine undurchsichtige (opaque) Antwort; in unserem Test war der Status `0`, der Typ `opaque` und der Body nicht lesbar. Das passt nur für Anfragen, deren Antwort Sie nie lesen.

### Ist CORS eine Sicherheitsfunktion für meine API?

Nein. CORS verhindert, dass eine Website mit den Cookies eines Besuchers die Daten einer anderen Website liest, aber jeder kann Ihre API weiterhin per Skript aufrufen. Schützen Sie die API mit Authentifizierung, Autorisierung und Rate Limits.

### Kann ein Proxy oder VPN einen CORS-Fehler beheben?

Nein. Der Browser vergleicht den Origin der Seite mit dem `Access-Control-Allow-Origin`-Header der Antwort; die IP-Adresse ist nicht Teil der Prüfung.

### Warum schlägt nur meine POST-Anfrage fehl, während GET funktioniert?

Das `POST` braucht wahrscheinlich einen Preflight, wegen eines JSON-Bodys, eines `Authorization`-Headers oder eines eigenen Headers. Beantwortet die API die `OPTIONS`-Anfrage nicht korrekt, sendet der Browser das `POST` nie. Suchen Sie den `OPTIONS`-Eintrag im Tab Network (Netzwerk), oder senden Sie den Preflight mit curl.

## Fazit

Ein CORS-Fehler bedeutet, dass der Browser die Antwort eines anderen Origins nicht an Ihr Skript übergibt; die Anfrage hat den Server meist erreicht. Lesen Sie den Grund in der Konsole, prüfen Sie den echten Status mit curl, und beheben Sie das Problem auf dem Server: exakte Origins, eine Antwort auf `OPTIONS`, die richtigen Methoden und Header, `Vary: Origin`. Nutzen Sie beim Entwickeln den Dev-Server-Proxy und für APIs, die Sie nicht kontrollieren, Ihr eigenes Backend. Datenerhebung gehört in serverseitigen Code, wo CORS nicht gilt; die Proxy-Typen für diese Arbeit finden Sie auf unserer Seite zu [Proxy-Diensten](/de/proxy).
