Cross-Origin Resource Sharing (CORS)

Ursprungsübergreifende Ressourcen sicher teilen

Mariko Kosaka

Die Same-Origin-Policy des Browsers blockiert das Lesen einer Ressource von einem anderen Ursprung. Dieser Mechanismus verhindert, dass schädliche Websites die Daten anderer Websites lesen, er verhindert jedoch auch eine legitime Verwendung.

Moderne Webanwendungen möchten häufig Ressourcen von einem anderen Ursprung abrufen, um beispielsweise JSON-Daten aus einer anderen Domain abzurufen oder Bilder von einer anderen Website in ein <canvas>-Element zu laden. Dabei kann es sich um öffentliche Ressourcen handeln, die für jeden lesbar sein sollen, deren Verwendung jedoch durch die Richtlinie für denselben Ursprung blockiert wird. Entwickler haben in der Vergangenheit Behelfslösungen wie JSONP verwendet.

Durch Cross-Origin Resource Sharing (CORS) wird dieses Problem standardisiert behoben. Wenn Sie CORS aktivieren, kann der Server dem Browser mitteilen, dass er eine zusätzliche Quelle verwenden kann.

Wie funktioniert eine Ressourcenanforderung im Web?

Anfrage und Antwort
Illustrierte Clientanfrage und Serverantwort.

Ein Browser und ein Server können mithilfe des Hypertext Transfer Protocol (HTTP) Daten über das Netzwerk austauschen. HTTP definiert die Kommunikationsregeln zwischen dem Anfragenden und dem Antwortenden, einschließlich der Informationen, die zum Abrufen einer Ressource erforderlich sind.

Der HTTP-Header handelt den Nachrichtenaustausch zwischen dem Client und dem Server aus und wird zur Festlegung des Zugriffs verwendet. Sowohl die Anfrage des Browsers als auch die Antwortnachricht des Servers werden in einen Header und einen Text unterteilt.

Informationen zur Nachricht wie den Nachrichtentyp oder die Codierung der Nachricht. Ein Header kann eine Vielzahl von Informationen enthalten, die als Schlüssel/Wert-Paare ausgedrückt werden. Anfrageheader und Antwortheader enthalten unterschiedliche Informationen.

Beispiel für einen Anfrageheader

Accept: text/html
Cookie: Version=1

Diese Kopfzeile entspricht der Anweisung „Ich möchte HTML als Antwort erhalten. Hier ist ein Keks, den ich habe.“

Beispiel für einen Antwortheader

Content-Encoding: gzip
Cache-Control: no-store

Dieser Header entspricht der Anweisung "Die Daten in dieser Antwort sind mit gzip codiert. Nicht im Cache speichern.“

Text

Die Nachricht selbst Dabei kann es sich um Nur-Text, ein binäres Bild, JSON, HTML oder viele andere Formate handeln.

Wie funktioniert CORS?

Mit der Richtlinie für denselben Ursprung wird der Browser angewiesen, ursprungsübergreifende Anfragen zu blockieren. Wenn Sie eine öffentliche Ressource aus einem anderen Ursprung benötigen, teilt der Server, der die Ressource bereitstellt, dem Browser mit, dass der Ursprung, der die Anfrage sendet, auf seine Ressource zugreifen kann. Der Browser merkt sich das und lässt Cross-Origin Resource Sharing für diese Ressource zu.

Schritt 1: Client- bzw. Browseranfrage

Wenn der Browser eine ursprungsübergreifende Anfrage sendet, fügt er einen Origin-Header mit dem aktuellen Ursprung (Schema, Host und Port) hinzu.

Schritt 2: Serverantwort

Wenn ein Server diesen Header sieht und den Zugriff erlauben möchte, fügt er der Antwort einen Access-Control-Allow-Origin-Header hinzu, der den anfragenden Ursprung angibt (oder *, um jeden Ursprung zuzulassen).

Schritt 3: Browser erhält Antwort

Wenn der Browser diese Antwort mit einem entsprechenden Access-Control-Allow-Origin-Header erkennt, gibt er die Antwortdaten an die Clientwebsite weiter.

Anmeldedaten für CORS freigeben

Aus Datenschutzgründen wird CORS normalerweise für anonyme Anfragen verwendet, bei denen der Anforderer nicht identifiziert wird. Wenn Sie mit CORS Cookies senden möchten, die den Absender identifizieren können, müssen Sie der Anfrage und Antwort zusätzliche Header hinzufügen.

Anfragen

Fügen Sie den Abrufoptionen credentials: 'include' hinzu, wie im folgenden Beispiel gezeigt. Dazu gehört das Cookie mit der Anfrage:

fetch('https://example.com', {
  mode: 'cors',
  credentials: 'include'
})

Antwort

Access-Control-Allow-Origin muss auf einen bestimmten Ursprung festgelegt werden (kein Platzhalter mit *) und Access-Control-Allow-Credentials auf true.

HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Credentials: true

Preflight-Anfragen für komplexe HTTP-Aufrufe

Wenn eine Webanwendung eine komplexe HTTP-Anfrage stellt, fügt der Browser am Anfang der Anfragekette eine Preflight-Anfrage hinzu.

Die CORS-Spezifikation definiert eine komplexe Anfrage so:

  • Eine Anfrage, bei der andere Methoden als GET, POST oder HEAD verwendet werden.
  • Eine Anfrage, die andere Header als Accept, Accept-Language oder Content-Language enthält.
  • Eine Anfrage mit einem anderen Content-Type-Header als application/x-www-form-urlencoded, multipart/form-data oder text/plain.

Browser erstellen automatisch alle erforderlichen Preflight-Anfragen und senden sie vor der eigentlichen Anfragenachricht. Die Preflight-Anfrage ist eine OPTIONS-Anfrage wie im folgenden Beispiel:

OPTIONS /data HTTP/1.1
Origin: https://example.com
Access-Control-Request-Method: DELETE

Serverseitig antwortet die die Anfrage empfangende Anwendung auf die Preflight-Anfrage mit Informationen zu den Methoden, die die Anwendung von diesem Ursprung akzeptiert:

HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Methods: GET, DELETE, HEAD, OPTIONS

Die Serverantwort kann auch einen Access-Control-Max-Age-Header enthalten, um die Dauer in Sekunden anzugeben, für die Preflight-Ergebnisse im Cache gespeichert werden sollen. Dadurch kann der Client mehrere komplexe Anfragen senden, ohne die Preflight-Anfrage wiederholen zu müssen.