Cross-Origin Resource Sharing (CORS)

Ressourcen zwischen Ursprungen sicher teilen

Mariko Kosaka

Die Same-Origin-Richtlinie des Browsers unterbindet das Lesen einer Ressource mit einem anderen Ursprung. Dieser Mechanismus verhindert, dass bösartige Websites Daten anderer Websites lesen, aber auch legitime Nutzungen.

Moderne Webanwendungen müssen häufig Ressourcen von einer anderen Quelle abrufen, z. B. JSON-Daten aus einer anderen Domain oder Bilder von einer anderen Website in ein <canvas>-Element laden. Dabei kann es sich um öffentliche Ressourcen handeln, die für jeden zugänglich sein sollten, aber die Same-Origin-Policy blockiert ihre Verwendung. Entwickler haben in der Vergangenheit Behelfslösungen wie JSONP verwendet.

Cross-Origin Resource Sharing (CORS) behebt dieses Problem auf standardisierte Weise. Wenn CORS aktiviert ist, kann der Server dem Browser mitteilen, dass er einen zusätzlichen Ursprung verwenden kann.

Wie funktioniert eine Ressourcenanfrage im Web?

Anfrage und Antwort
Illustrierte Clientanfrage und Serverantwort.

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

Der HTTP-Header verhandelt den Nachrichtenaustausch zwischen dem Client und dem Server und wird verwendet, um den Zugriff zu bestimmen. Sowohl die Anfrage des Browsers als auch die Antwortnachricht des Servers sind in einen Header und einen Textkörper unterteilt.

Informationen zur Nachricht, z. B. der Nachrichtentyp oder die Codierung der Nachricht. Ein Header kann verschiedene Informationen in Form von Schlüssel/Wert-Paaren enthalten. Der Anfrageheader und der Antwortheader enthalten unterschiedliche Informationen.

Beispiel für einen Anfrageheader

Accept: text/html
Cookie: Version=1

Dieser Header entspricht der Aussage „Ich möchte als Antwort HTML erhalten. Hier ist ein Keks, den ich habe.“

Beispiel für einen Antwortheader

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

Dieser Header entspricht der Aussage „Die Daten in dieser Antwort sind mit gzip codiert. Speichern Sie diese Informationen nicht im Cache.“

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?

Die Same-Origin-Richtlinie weist den Browser an, quellenübergreifende Anfragen zu blockieren. Wenn Sie eine öffentliche Ressource von einem anderen Ursprung benötigen, teilt der Server, der die Ressource bereitstellt, dem Browser mit, dass der Ursprung, von dem die Anfrage gesendet wird, auf die Ressource zugreifen kann. Der Browser merkt sich das und erlaubt Cross-Origin Resource Sharing für diese Ressource.

Schritt 1: Clientanfrage (Browser)

Wenn der Browser eine ursprungsübergreifende Anfrage stellt, 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 zulassen möchte, fügt er der Antwort einen Access-Control-Allow-Origin-Header hinzu, in dem der Ursprung der Anfrage angegeben ist (oder *, um jeden Ursprung zuzulassen).

Schritt 3: Browser empfängt Antwort

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

Anmeldedaten mit CORS teilen

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

Anfrage

Fügen Sie den Abrufoptionen credentials: 'include' hinzu, wie im folgenden Beispiel gezeigt. Dies schließt das Cookie mit der Anfrage folgendermaßen ein:

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 muss auf true festgelegt sein.

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 dem Anfang der Anfragekette eine Preflight-Anfrage hinzu.

Die CORS-Spezifikation definiert eine komplexe Anfrage so:

  • Eine Anfrage, die andere Methoden als GET, POST oder HEAD verwendet.
  • 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 Anwendung, die die Anfrage empfängt, auf die Preflight-Anfrage mit Informationen über die 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 für das Caching von Preflight-Ergebnissen anzugeben. So kann der Client mehrere komplexe Anfragen senden, ohne die Preflight-Anfrage wiederholen zu müssen.