TATECHATLAS
◎ Deutsch
Web und APIs

curl funktioniert, fetch schlägt fehl: CORS und Preflight diagnostizieren

Unterscheiden Sie den Zugriff auf eine Antwort von dem Senden einer Anfrage, prüfen Sie ein OPTIONS-Preflight und konfigurieren Sie explizite Ursprünge für Anfragen im Browser mit Anmeldeinformationen.

Auf dieser Seite

curl setzt keine Browser-CORS-Regeln durch. Eine erfolgreiche curl-Antwort beweist daher nicht, dass JavaScript von einem anderen Ursprung darauf zugreifen kann. Prüfen Sie das Browser-Netzwerkpanel: Einige Anfragen werden direkt gesendet, während Anfragen wie ein JSON-POST oder eine mit Authorization in der Regel ein OPTIONS-Preflight benötigen. Prüfen Sie Preflight und tatsächliche Antwort getrennt, unter Verwendung des exakten Ursprungs der Seite sowie der beabsichtigten Methode und der Header.

Ein Ursprung ist Schema, Host und Port

Eine Seite unter https://app.example und eine API unter https://api.example haben unterschiedliche Ursprünge, auch wenn ihre Namen ein Suffix teilen. Das Ändern des Ports oder das Wechseln von HTTP zu HTTPS kann ebenfalls den Ursprung ändern. Beginnen Sie mit dem tatsächlichen Origin-Header des Browsers statt eine Angabe aus dem Bereitstellungsnamen zu erraten.

CORS regelt, ob ein Browser eine cross-origin-Antwort für ein Skript freigibt. Es ist keine API-Authentifizierung und verhindert nicht, dass curl oder ein anderer Server die API aufruft. Bewahren Sie Autorisierung und Schutz vor unerwünschten state-changing-Anfragen in der Anwendung.

Direkte Anfragen und Preflight sind unterschiedliche Wege

Ein GET ohne nicht-sicherende Anfrage-Header kann oft ohne Preflight gesendet werden. Bestimmte POST-Anfragen mit form-kompatiblen Inhalts-Typen können ebenfalls diesen Weg nehmen. Die Antwort benötigt weiterhin entsprechende CORS-Header, bevor JavaScript darauf zugreifen kann.

Eine Anfrage mit application/json, Authorization oder einer Methode wie PUT erfordert in der Regel Preflight. Der Browser fragt ab, welche Methoden und Anfrage-Header erlaubt sind, bevor die eigentliche Anfrage gesendet wird. Anmeldeinformationen allein bedeuten nicht, dass jede Anfrage preflighted werden muss; prüfen Sie die vollständigen Anfragebedingungen.

Ein konkretes JSON-POST-Beispiel

Nehmen Sie an, eine Seite auf https://app.example sendet ein JSON-POST an https://api.example/items mit einem Bearer-Token. Diese sind illustrative Hostnamen und ein hypothetisches Endpunkt, keine funktionierenden Dienste. Der folgende Code gehört in die Browser-Seite; das Token ist ein Platzhalter.

Ohne ein gültiges zwischengespeichertes Preflight-Ergebnis erwarten Sie eine OPTIONS-Anfrage, die POST und die Authorization- und Content-Type-Header ankündigt. Der Browser baut diese Preflight-Header auf; die Anwendung JavaScript sollte diese nicht manuell setzen.

fetch('https://api.example/items', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer DEMO_TOKEN'
  },
  body: JSON.stringify({name: 'sample'})
}).then(response => {
  if (!response.ok) throw new Error('HTTP ' + response.status);
  return response.json();
}).then(console.log).catch(console.error);

Lesen Sie das Preflight, bevor Sie Server-Einstellungen ändern

In den Entwicklertools bewahren Sie das Netzwerkprotokoll auf und suchen nach OPTIONS. Sein Origin sollte die Seite identifizieren, und Access-Control-Request-Method sollte in diesem Beispiel POST sein. Access-Control-Request-Headers listet die angeforderten nicht-sicheren Header auf. Die Groß-/Kleinschreibung der Header-Namen ist nicht maßgeblich.

Eine geeignete erfolgreiche Preflight-Antwort ermöglicht den spezifischen Ursprung, die Methode und die Header. OPTIONS sollte nicht das für den folgenden POST vorgesehene Bearer-Token erfordern, weil das Preflight diesen Anwendung-Header nicht trägt. Die Authentifizierung bleibt für die tatsächliche Anfrage erforderlich.

HTTP/1.1 204 No Content
Access-Control-Allow-Origin: https://app.example
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: POST
Access-Control-Allow-Headers: authorization, content-type
Vary: Origin

Die tatsächliche Antwort benötigt eigene Genehmigung

Das Vorbeitreten des Preflight ist nur der erste Schritt. Die POST-Antwort benötigt ebenfalls Access-Control-Allow-Origin. Prüfen Sie Fehler ebenso wie erfolgreiche Antworten: Eine Authentifizierungsfehler ohne entsprechenden CORS-Header kann für JavaScript wie ein generischer Netzwerkfehler aussehen.

Wenn OPTIONS erfolgreich ist, aber POST fehlschlägt, prüfen Sie dessen Status, Anwendungsprotokolle und Antwort-Header. Eine CORS-Nachricht beweist nicht, dass Authentifizierung oder Anwendungslogik erfolgreich waren. Umgekehrt kann eine direkt gesendete Anfrage den Server erreicht haben, obwohl der Browser den Skript-Zugriff auf die Antwort blockiert.

Cookies erfordern eine explizite Ursprungsverwaltung

Um cross-origin-Cookies mit fetch zu senden, verwenden Sie credentials: include. Der Server muss Anmeldeinformationen erlauben und muss mit dem explizit erlaubten Ursprung antworten, nicht mit Access-Control-Allow-Origin: *. Die Browser-Cookie-Regeln, einschließlich SameSite und Drittanbieter-Einschränkungen, gelten weiterhin.

Führen Sie eine Erlaubnisliste bei der Reflektion eines eingehenden Ursprungs durch; das blinden Widerspiegeln jedes Ursprungs gewährt zu weitreichenden Zugriff. Wenn eine Antwort vom Ursprung abhängt, hilft Vary: Origin Caches, diese Varianten zu trennen. Übereinstimmen Sie den Ursprung genau; Pfade sind nicht Teil eines Ursprungs.

Vergleichen Sie die Browser-Anfrage mit dem Befehlszeilen-Aufruf

Ein Befehlszeilen-Aufruf kann helfen, den HTTP-Status und die zurückgegebenen Header zu prüfen, aber er reproduziert nicht die Durchsetzung des Browsers. Vergleichen Sie Methode, Origin, Anfrage-Header, Weiterleitungen und die Handhabung von Anmeldeinformationen. Ein erfolgreicher einfacher GET diagnostiziert nicht einen fehlschlagenden authentifizierten JSON-POST.

Verwenden Sie mode: no-cors nicht, um lesbare API-Daten zu erhalten. Es kann eine opake Antwort erzeugen, deren Körper und Status für das Skript nicht verfügbar sind. Beheben Sie stattdessen die Server-Genehmigung für die beabsichtigte Anfrage, anstatt ein opakes Ergebnis als erfolgreiche Integration zu behandeln.

Eine kurze Diagnose-Reihenfolge

Bestätigen Sie zuerst die Ursprünge von Seite und API. Unterscheiden Sie dann eine direkte Anfrage von OPTIONS gefolgt von der tatsächlichen Methode. Prüfen Sie erlaubten Ursprung, Methode und Header beim Preflight; prüfen Sie die Ursprungs-Erlaubnis bei der Anwendung-Antwort. Schließlich prüfen Sie Authentifizierung und Cookie-Politik.

Das Preflight-Caching kann eine vorherige OPTIONS-Anfrage unterdrücken. Schlussfolgern Sie nicht, dass eine Anfrage nur deshalb einfach geworden ist, weil keine neue OPTIONS-Eintragung erscheint. Diese Reihenfolge verengt den Fehler auf einen bestimmten Austausch, ohne die API-Zugriffssteuerungen zu schwächen.

Was Sie prüfen sollten

  • Protokollieren Sie den exakten Browser-Origin, die Methode und die angeforderten Header.
  • Prüfen Sie sowohl OPTIONS als auch die tatsächliche Antwort, einschließlich Fehler.
  • Verwenden Sie einen expliziten erlaubten Ursprung für Anfragen mit Anmeldeinformationen.
  • Halten Sie Authentifizierung und Schutz vor Anfrage-Fälschung getrennt von CORS.

Dieser Leitfaden behandelt gängige fetch-Anfragen. Weiterleitungen, Cookie-Politik, Netzwerkfehler und Anwendung-Authentifizierung können zusätzliche Fehler verursachen; CORS-Header lösen nicht alle davon.

Quellen

  1. MDN: CORS ↗
  2. MDN: preflight request ↗
Nach oben ↑