Es ermöglicht dem Browser, XMLHttpRequest -Anforderungen an Cross-Origin-Server auszugeben und so die Einschränkung zu überwinden, dass AJAX nur in demselben Ursprung verwendet werden kann.
In diesem Artikel wird der interne Mechanismus von CORs im Detail vorgestellt.
(Fotobeschreibung: Aufgenommen im Oasis Park in Al Ain, VAE)
1. Einführung
CORS erfordert sowohl Browser- als auch Serverunterstützung. Derzeit unterstützen alle Browser diese Funktion, und der IE -Browser kann nicht niedriger sein als IE10.
Der gesamte CORS -Kommunikationsprozess wird vom Browser automatisch abgeschlossen und erfordert keine Benutzerbeteiligung. Für Entwickler unterscheidet sich die CORS -Kommunikation nicht von der gleichen Ursprung AJAX -Kommunikation, und der Code ist genau der gleiche. Sobald der Browser festgestellt hat, dass AJAX Cross-ORIGIN anfordert, wird automatisch einige zusätzliche Header-Informationen hinzugefügt, und manchmal wird es eine zusätzliche Anfrage geben, der Benutzer wird dies jedoch nicht spüren.
Daher ist der Schlüssel zur Implementierung der CORS -Kommunikation der Server. Solange der Server die CORS-Schnittstelle implementiert, kann die Kommunikation mit der Querveranstalter durchgeführt werden.
Zwei Anfragen
Der Browser unterteilt CORS-Anfragen in zwei Kategorien: einfache Anfrage und nicht so nur eine einfache Anfrage.
Solange die folgenden zwei Hauptbedingungen gleichzeitig erfüllt sind, handelt es sich um eine einfache Anfrage.
(1) Die Anforderungsmethode ist eine der folgenden drei Methoden:
Headgetpost
(2) Die Header -Informationen von HTTP überschreiten die folgenden Felder nicht:
AcceptAccecece-Sprachguss-Languagelast-Event-Idcontent-Typ: Nur auf drei Werte application/x-www-form-urlencoded , multipart/form-data , text/plain
Jeder, der die beiden oben genannten Bedingungen nicht gleichzeitig erfüllt, ist eine nicht einfache Anfrage.
Der Browser -Umgang mit diesen beiden Anfragen ist unterschiedlich.
3. Einfacher Anfrage 3.1 Grundprozess
Für einfache Anfragen stellt der Browser die CORS -Anfrage direkt aus. Fügen Sie den Header -Informationen insbesondere einen Origin hinzu.
Das Folgende ist ein Beispiel. Der Browser stellte fest, dass diese Cross-Origin-Ajax-Anfrage eine einfache Anforderung war und die Header-Informationen automatisch ein Origin hinzugefügt hat.
GET /cors HTTP/1.1Origin: http://api.bob.comHost: api.alice.comAccept-Language: en-USConnection: keep-aliveUser-Agent: Mozilla/5.0...
In den oben genannten Header -Informationen wird Origin verwendet, um anzugeben, aus welcher Quelle (Protokoll + Domänenname + Port) die Anforderung stammt. Basierend auf diesem Wert entscheidet der Server, ob der Anfrage zustimmen soll.
Wenn die durch Origin angegebene Quelle nicht innerhalb des Berechtigungsbereichs liegt, gibt der Server eine normale HTTP -Antwort zurück. Der Browser stellte fest, dass die Headerinformationen dieser Antwort nicht das Feld Access-Control-Allow-Origin enthielten (siehe unten für Einzelheiten), so dass ein Fehler aufgetreten war und somit ein Fehler geworfen wurde, der durch die onerror Rückruffunktion von XMLHttpRequest erfasst wurde. Beachten Sie, dass dieser Fehler nicht durch den Statuscode identifiziert werden kann, da der Statuscode der HTTP -Antwort möglicherweise 200 beträgt.
Wenn sich der vom Origin angegebene Domänenname innerhalb des Berechtigungsbereichs befindet, verfügt die vom Server zurückgegebene Antwort über mehrere zusätzliche Headerfelder.
Access-Control-Allow-Origin: http://api.bob.comAccess-Control-Allow-Credentials: trueAccess-Control-Expose-Headers: FooBarContent-Type: text/html; charset=utf-8
Unter den oben genannten Headerinformationen gibt es drei Felder zu CORS-Anfragen, die alle mit Access-Control- .
(1) Zugangskontroll-Allow-Origin
Dieses Feld ist erforderlich. Sein Wert ist entweder der Wert Origin zum Zeitpunkt der Anfrage oder A * , was angibt, dass die Anfrage für einen Domain -Namen akzeptiert wird.
(2) Zugriffskontroll-Allow-Kredite
Dieses Feld ist optional. Sein Wert ist ein Boolean -Wert, der angibt, ob das Senden von Cookies zulässig ist. Standardmäßig sind Cookies nicht in CORS -Anfragen enthalten. Auf true eingestellt, was bedeutet, dass der Server dies explizit zulässt. Cookies können in die Anfrage aufgenommen und gemeinsam an den Server gesendet werden. Dieser Wert kann nur auf true eingestellt werden. Wenn der Server keine Cookies vom Browser sendet, löschen Sie das Feld.
(3) Zugriffskontroll-Expose-Header
Dieses Feld ist optional. Wenn CORS anfordert, kann getResponseHeader() XMLHttpRequest Objekts nur 6 grundlegende Felder erhalten: Cache-Control , Content-Language , Content-Type , Expires , Last-Modified Pragma . Wenn Sie andere Felder erhalten möchten, müssen Sie diese in Access-Control-Expose-Headers angeben. Das obige Beispiel gibt an, dass getResponseHeader('FooBar') den Wert FooBar -Feldes zurückgeben kann.
3.2 Withcredentials Attribut
Wie oben erwähnt, senden CORS -Anfragen standardmäßig keine Cookies- und HTTP -Authentifizierungsinformationen. Wenn Sie einerseits Cookies an den Server senden möchten, müssen Sie den Server einverstanden und das Feld Access-Control-Allow-Credentials angeben.
Access-Control-Allow-Credentials: true Andererseits muss der Entwickler die Eigenschaft withCredentials in der AJAX -Anfrage öffnen.
var xhr = new XMLHttpRequest();xhr.withCredentials = true;Andernfalls sendet der Browser nicht, selbst wenn der Server zustimmt, Cookies zu senden. Alternativ verlangt der Server, dass Cookies festgelegt werden müssen, und der Browser wird ihn nicht behandeln.
Wenn jedoch die Einstellung withCredentials ausgelassen wird, senden einige Browser weiterhin Cookies zusammen. Zu diesem Zeitpunkt können Sie explizit withCredentials schließen.
xhr.withCredentials = false; Es ist zu beachten, dass, wenn Sie Cookies senden möchten, Access-Control-Allow-Origin nicht als Sternchen festgelegt werden kann, und Sie müssen einen expliziten Domänennamen angeben, der mit der angeforderten Webseite übereinstimmt. Gleichzeitig folgen Cookies immer noch die gleichorientierte Richtlinie. Nur Cookies, die mit Server -Domainnamen festgelegt werden, werden hochgeladen. Cookies aus anderen Domainnamen werden nicht hochgeladen und document.cookie Kochen im Original-Webseitencode (Kreuz- original) können Cookies unter dem Server-Domänennamen nicht lesen.
4. Nicht-Einfache Anfrage 4.1 Anfrage vor dem Flug
Eine nicht-einfache Anfrage ist eine Anfrage, die spezielle Anforderungen für den Server enthält, z. B. wird die Anforderungsmethode PUT oder DELETE , oder Content-Type ist application/json .
Eine CORS -Anfrage, die keine einfache Anfrage darstellt, fügt vor der offiziellen Kommunikation eine HTTP -Abfrageanforderung hinzu, die als "Preflight" -Anforderung bezeichnet wird.
Der Browser fragt zuerst den Server, ob sich der Domänenname, auf dem sich die aktuelle Webseite befindet, auf der Lizenzliste des Servers befindet und welche HTTP -Verben und Headerfelder verwendet werden können. Nur wenn eine positive Antwort empfangen wird, gibt der Browser eine formelle XMLHttpRequest -Anfrage aus, sonst wird ein Fehler gemeldet.
Unten finden Sie ein Browser -JavaScript -Skript.
var url = 'http://api.alice.com/cors';var xhr = new XMLHttpRequest();xhr.open('PUT', url, true);xhr.setRequestHeader('X-Custom-Header', 'value');xhr.send();
Im obigen Code wird die HTTP-Anforderungsmethode PUT und sendet eine benutzerdefinierte Header-Informationen X-Custom-Header .
Der Browser stellte fest, dass es sich um eine nicht einfache Anfrage handelte. Daher gab er automatisch eine "Vor-Flug" -Anforderung aus, wobei der Server bestätigt, dass dies angefordert werden kann. Unten finden Sie die HTTP -Header -Informationen für diese "Preflight" -Anforderung.
OPTIONS /cors HTTP/1.1Origin: http://api.bob.comAccess-Control-Request-Method: PUTAccess-Control-Request-Headers: X-Custom-HeaderHost: api.alice.comAccept-Language: en-USConnection: keep-aliveUser-Agent: Mozilla/5.0... Die von der Anforderung "Preflight" verwendete Anforderungsmethode ist OPTIONS , die angibt, dass diese Anfrage zum Nachfragen verwendet wird. In den Header -Informationen ist das Schlüsselfeld Origin und gibt an, aus welcher Quelle die Anforderung stammt.
Zusätzlich zum Feld " Origin enthält die Header -Informationen der Anfrage "Vorfile" zwei spezielle Felder.
(1) Zugangskontroll-Request-Methode
Dieses Feld ist erforderlich, um aufzulisten, welche HTTP -Methoden für die CORS -Anfrage des Browsers verwendet werden. Das obige Beispiel wird PUT .
(2) Zugangskontroll-Request-Header
In diesem Feld handelt es sich um eine von Kommas getrennte Zeichenfolge, die das Feld zusätzlicher Headerinformationen angibt, das die Browser-CORS-Anfrage sendet. Das obige Beispiel ist X-Custom-Header .
4.2 Antwort auf Anfragen vor dem Flug
Nachdem der Server die Anforderung "Preflight" empfangen hat, bestätigen Sie nach Überprüfung Origin Access-Control-Request-Method und Access-Control-Request-Headers Felder, dass Cross-Origin-Anfragen zulässig sind und Sie antworten können.
HTTP/1.1 200 OKDate: Mon, 01 Dec 2008 01:15:39 GMTServer: Apache/2.0.61 (Unix)Access-Control-Allow-Origin: http://api.bob.comAccess-Control-Allow-Methods: GET, POST, PUTAccess-Control-Allow-Headers: X-Custom-HeaderContent-Type: text/html; charset=utf-8Content-Encoding: gzipContent-Length: 0Keep-Alive: timeout=2, max=100Connection: Keep-AliveContent-Type: text/plain
In der obigen HTTP-Antwort ist der Schlüssel das Feld Access-Control-Allow-Origin , was bedeutet, dass http://api.bob.com Daten anfordern kann. Dieses Feld kann auch auf ein Sternchen eingestellt werden, um einer Queroor-Anfrage zuzustimmen.
Access-Control-Allow-Origin: *
Wenn der Browser die Anforderung "Preflight" negiert, wird eine normale HTTP-Antwort zurückgegeben, es gibt jedoch keine CORS-bezogenen Headerfelder. Zu diesem Zeitpunkt stellt der Browser fest, dass der Server der Vorfilsanforderung nicht zustimmt, sodass ein Fehler durch die onerror -Rückruffunktion XMLHttpRequest -Objekts ausgelöst und erfasst wird. Die Konsole druckt die folgende Fehlermeldung aus.
XMLHttpRequest cannot load http://api.alice.com.Origin http://api.bob.com is not allowed by Access-Control-Allow-Origin.
Andere CORS-bezogene Felder, auf die der Server reagiert, sind wie folgt.
Access-Control-Allow-Methods: GET, POST, PUTAccess-Control-Allow-Headers: X-Custom-HeaderAccess-Control-Allow-Credentials: trueAccess-Control-Max-Age: 1728000(1) Zugriffskontroll-Bahn-Methoden
Dieses Feld ist erforderlich, und sein Wert ist eine von Kommas getrennte Zeichenfolge, die alle vom Server unterstützten Cross-Domain-Anforderungsmethoden angibt. Beachten Sie, dass alle unterstützten Methoden zurückgegeben werden, nicht nur der vom Browser angeforderte. Dies soll mehrere "Preflight" -Anfragen vermeiden.
(2) Zugangskontroll-Allowader
Wenn die Browseranforderung Access-Control-Request-Headers enthält, ist Access-Control-Allow-Headers erforderlich. Es handelt sich auch um eine von Kommas getrennte Zeichenfolge, die angibt, dass alle vom Server unterstützten Headerfelder nicht auf Felder beschränkt sind, die vom Browser in "Preflight" angefordert werden.
(3) Zugriffskontroll-Allow-Kredite
Dieses Feld hat die gleiche Bedeutung wie es ist, wenn es auf einfache Weise angefordert wird.
(4) Zugangskontroll-Max-Alter
Dieses Feld ist optional und wird verwendet, um die Gültigkeitsdauer dieser Preflight -Anforderung in Sekunden anzugeben. In den obigen Ergebnissen beträgt die Gültigkeitsdauer 20 Tage (1728.000 Sekunden), was bedeutet, dass die Antwort für 1728.000 Sekunden (d. H. 20 Tage) zwischengespeichert wird. Während dieser Zeit ist keine andere Anfrage vor dem Flug erforderlich.
4.3 Normale Anfragen und Antworten aus dem Browser
Sobald der Server die Anforderung "Preflight" überschritten hat, gibt es jedes Mal, wenn die normale CORS -Anfrage des Browsers eine einfache Anfrage entspricht, ein Origin . Die Reaktion des Servers hat auch ein Access-Control-Allow-Origin Header-Feld.
Nachfolgend finden Sie die normale CORS -Anfrage des Browsers nach der Anforderung "Vorflug".
PUT /cors HTTP/1.1Origin: http://api.bob.comHost: api.alice.comX-Custom-Header: valueAccept-Language: en-USConnection: keep-aliveUser-Agent: Mozilla/5.0...
Das Origin der obigen Header -Informationen wird vom Browser automatisch hinzugefügt.
Unten finden Sie die normale Antwort vom Server.
Access-Control-Allow-Origin: http://api.bob.comContent-Type: text/html; charset=utf-8
In den oben genannten Headerinformationen muss das Feld Access-Control-Allow-Origin in jeder Antwort einbezogen werden.
5. Vergleich mit JSONP
CORS wird in dem gleichen Zweck wie JSONP verwendet, ist aber mächtiger als JSONP.
JSONP unterstützt nur GET -Anfragen, CORS unterstützt alle Arten von HTTP -Anfragen. Der Vorteil von JSONP besteht darin, dass es altmodische Browser unterstützt und Daten von Websites anfordern kann, die CORs nicht unterstützen.
(über)