Il permet au navigateur d'émettre des demandes XMLHttpRequest pour croiser les serveurs d'origine, surmontant ainsi la limitation que l'Ajax ne peut être utilisée que dans la même origine.
Cet article présente en détail le mécanisme interne des COR.
(Description de la photo: prise à Oasis Park à Al Ain, EAU)
1. Introduction
CORS nécessite à la fois la prise en charge du navigateur et du serveur. Actuellement, tous les navigateurs prennent en charge cette fonction et le navigateur IE ne peut pas être inférieur à IE10.
L'ensemble du processus de communication CORS est automatiquement terminé par le navigateur et ne nécessite pas de participation des utilisateurs. Pour les développeurs, la communication CORS n'est pas différente de la même communication Ajax d'origine, et le code est exactement le même. Une fois que le navigateur découvre que Ajax demande à l'origine croisée, il ajoutera automatiquement des informations d'en-tête supplémentaires, et parfois il y aura une demande supplémentaire, mais l'utilisateur ne le ressentira pas.
Par conséquent, la clé pour implémenter la communication COR est le serveur. Tant que le serveur implémente l'interface CORS, la communication croisée peut être effectuée.
Deux demandes
Le navigateur divise les demandes CORS en deux catégories: demande simple et demande pas si simple.
Tant que les deux conditions principales suivantes sont remplies en même temps, c'est une simple demande.
(1) La méthode de demande est l'une des trois méthodes suivantes:
Headgetpost
(2) Les informations d'en-tête de HTTP ne dépassent pas les champs suivants:
AcceptAccept-LanguageContent-Languagelast-Event-IdContent-Type: uniquement limité à trois valeurs application/x-www-form-urlencoded , multipart/form-data , text/plain
Quiconque ne remplit pas les deux conditions ci-dessus en même temps est une demande non simple.
Le traitement par le navigateur de ces deux demandes est différent.
3. Demande simple 3.1 Processus de base
Pour les demandes simples, le navigateur émet directement la demande de CORS. Plus précisément, ajoutez un champ Origin aux informations d'en-tête.
Ce qui suit est un exemple. Le navigateur a constaté que cette demande Ajax d'origine transversale était une demande simple, et elle a automatiquement ajouté un champ Origin aux informations d'en-tête.
GET /cors HTTP/1.1Origin: http://api.bob.comHost: api.alice.comAccept-Language: en-USConnection: keep-aliveUser-Agent: Mozilla/5.0...
Dans les informations d'en-tête ci-dessus, Origin est utilisé pour indiquer la source (protocole + nom de domaine + port). La demande provient. Sur la base de cette valeur, le serveur décide d'accepter la demande.
Si la source spécifiée par Origin n'est pas dans la portée de l'autorisation, le serveur renvoie une réponse HTTP normale. Le navigateur a constaté que les informations d'en-tête de cette réponse ne contenaient pas le champ Access-Control-Allow-Origin (voir ci-dessous pour plus de détails), il a donc été connu qu'une erreur se produisait, et donc une erreur a été lancée, qui a été capturée par la fonction de rappel onerror de XMLHttpRequest . Notez que cette erreur ne peut pas être identifiée par le code d'état, car le code d'état de la réponse HTTP peut être de 200.
Si le nom de domaine spécifié par Origin est dans la portée de l'autorisation, la réponse renvoyée par le serveur aura plusieurs champs d'en-tête supplémentaires.
Access-Control-Allow-Origin: http://api.bob.comAccess-Control-Allow-Credentials: trueAccess-Control-Expose-Headers: FooBarContent-Type: text/html; charset=utf-8
Parmi les informations d'en-tête ci-dessus, il y a trois champs liés aux demandes CORS, tous commençant par Access-Control- .
(1) Access-Control-Allow-Origin
Ce champ est obligatoire. Sa valeur est soit la valeur du champ Origin au moment de la demande, soit A * , indiquant que la demande de tout nom de domaine est acceptée.
(2) Accès-contrôle-allore-créatifs
Ce champ est facultatif. Sa valeur est une valeur booléenne indiquant l'opportunité d'autoriser l'envoi de cookies. Par défaut, les cookies ne sont pas inclus dans les demandes CORS. Réglé sur true , ce qui signifie que le serveur le permet explicitement. Les cookies peuvent être inclus dans la demande et envoyés au serveur ensemble. Cette valeur ne peut être définie que sur true . Si le serveur n'envoie pas de cookies par le navigateur, supprimez le champ.
(3) Access-Control-Expose-Headers
Ce champ est facultatif. Lorsque CORS demande, getResponseHeader() de XMLHttpRequest ne peut obtenir que 6 champs de base: Cache-Control , Content-Language , Content-Type , Expires , Last-Modified , Pragma . Si vous souhaitez obtenir d'autres champs, vous devez les spécifier dans Access-Control-Expose-Headers . L'exemple ci-dessus spécifie que getResponseHeader('FooBar') peut renvoyer la valeur du champ FooBar .
3.2 Attribut de recrutement avec
Comme mentionné ci-dessus, les demandes CORS n'envoient pas les cookies et les informations d'authentification HTTP par défaut. Si vous souhaitez envoyer des cookies au serveur, d'une part, vous avez besoin que le serveur soit d'accord et spécifiez le champ Access-Control-Allow-Credentials .
Access-Control-Allow-Credentials: true D'un autre côté, le développeur doit ouvrir la propriété withCredentials dans la demande AJAX.
var xhr = new XMLHttpRequest();xhr.withCredentials = true;Sinon, le navigateur n'enverra pas même si le serveur accepte d'envoyer des cookies. Alternativement, le serveur nécessite le réglage des cookies et le navigateur ne le gérera pas.
Cependant, si le paramètre withCredentials est omis, certains navigateurs enverront toujours des cookies. À l'heure actuelle, vous pouvez explicitement fermer withCredentials .
xhr.withCredentials = false; Il convient de noter que si vous souhaitez envoyer des cookies, Access-Control-Allow-Origin ne peut pas être défini comme un astérisque, et vous devez spécifier un nom de domaine explicite conformément à la page Web demandée. Dans le même temps, les cookies suivent toujours la politique d'origine homosexuelle. Seuls les cookies définis avec les noms de domaine du serveur seront téléchargés. Les cookies des autres noms de domaine ne seront pas téléchargés, et document.cookie dans le code de page Web d'origine (original) ne peut pas lire les cookies sous le nom de domaine du serveur.
4. Demande non simple 4.1 Demande de pré-vol
Une demande non simple est une demande qui a des exigences spéciales pour le serveur, telles que la méthode de demande est PUT ou DELETE , ou Content-Type est application/json .
Une demande CORS qui n'est pas une demande simple ajoutera une demande de requête HTTP avant la communication officielle, qui s'appelle une demande "Fillight".
Le navigateur demande d'abord au serveur si le nom de domaine sur lequel se trouve la page Web actuelle se trouve sur la liste des licences du serveur et quels verbes HTTP et champs d'en-tête peuvent être utilisés. Ce n'est que lorsqu'une réponse positive sera reçue que le navigateur émettra une demande formelle XMLHttpRequest , sinon une erreur sera signalée.
Vous trouverez ci-dessous un script JavaScript de navigateur.
var url = 'http://api.alice.com/cors';var xhr = new XMLHttpRequest();xhr.open('PUT', url, true);xhr.setRequestHeader('X-Custom-Header', 'value');xhr.send();
Dans le code ci-dessus, la méthode de demande HTTP est PUT et envoie une information d'en-tête personnalisée X-Custom-Header .
Le navigateur a constaté qu'il s'agissait d'une demande non simple, il a donc automatiquement émis une demande "pré-vol", obligeant le serveur à confirmer que cela peut être demandé. Vous trouverez ci-dessous les informations d'en-tête HTTP pour cette demande "Facler".
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... La méthode de demande utilisée par la demande "Fillight" est OPTIONS , indiquant que cette demande est utilisée pour s'enquérir. Dans les informations d'en-tête, le champ de clé est Origin , indiquant de quelle source provient la demande.
En plus du champ Origin , les informations d'en-tête de la demande "Facler" comprennent deux champs spéciaux.
(1) l'accès-contrôle-request-méthode
Ce champ est nécessaire pour répertorier les méthodes HTTP utilisées pour la demande CORS du navigateur. L'exemple ci-dessus est PUT .
(2) Access-Control-Request-Headers
Ce champ est une chaîne séparée par des virgules qui spécifie le champ d'informations d'en-tête supplémentaire que la demande CORS du navigateur enverra. L'exemple ci-dessus est X-Custom-Header .
4.2 Réponse aux demandes avant le vol
Une fois que le serveur a reçu la demande "Fillight", après avoir vérifié Origin , les champs Access-Control-Request-Method et Access-Control-Request-Headers , confirmez que les demandes d'origine croisée sont autorisées et vous pouvez répondre.
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
Dans la réponse HTTP ci-dessus, la clé est le champ Access-Control-Allow-Origin , ce qui signifie que http://api.bob.com peut demander des données. Ce champ peut également être défini sur un astérisque pour accepter toute demande d'origine croisée.
Access-Control-Allow-Origin: *
Si le navigateur annule la demande "Facler", une réponse HTTP normale sera renvoyée, mais il n'y a pas de champs d'en-tête liés à COR. À l'heure actuelle, le navigateur déterminera que le serveur n'accepte pas la demande de pré-léger, donc une erreur est déclenchée et capturée par la fonction de rappel onerror de XMLHttpRequest . La console imprimera le message d'erreur suivant.
XMLHttpRequest cannot load http://api.alice.com.Origin http://api.bob.com is not allowed by Access-Control-Allow-Origin.
Les autres champs liés aux CORS auxquels le serveur répond sont les suivants.
Access-Control-Allow-Methods: GET, POST, PUTAccess-Control-Allow-Headers: X-Custom-HeaderAccess-Control-Allow-Credentials: trueAccess-Control-Max-Age: 1728000(1) les méthodes d'accès à l'allow
Ce champ est requis et sa valeur est une chaîne séparée par des virgules indiquant toutes les méthodes de demande de domaine croisé prise en charge par le serveur. Notez que toutes les méthodes prises en charge sont retournées, pas seulement celle demandée par le navigateur. Il s'agit d'éviter plusieurs demandes de "Ferflight".
(2) Access-Control-Allow-Headers
Si la demande du navigateur comprend Access-Control-Request-Headers , Access-Control-Allow-Headers est requis. Il s'agit également d'une chaîne séparée par des virgules indiquant que tous les champs d'en-tête pris en charge par le serveur ne sont pas limités aux champs demandés par le navigateur dans "Fiflight".
(3) accès-contrôle-allow-crédentiels
Ce champ a la même signification que lorsqu'il est demandé de manière simple.
(4) Access-Control-Max-Age
Ce champ est facultatif et est utilisé pour spécifier la période de validité de cette demande de premier plan, en quelques secondes. Dans les résultats ci-dessus, la période de validité est de 20 jours (1728 000 secondes), ce qui signifie que la réponse est mise en cache pendant 1728 000 secondes (c'est-à-dire 20 jours). Au cours de cette période, aucune autre demande de premier plan n'est requise.
4.3 Demandes et réponses normales du navigateur
Une fois que le serveur transmet la demande "Fillight", chaque fois que la demande normale CORS du navigateur est la même chose qu'une simple demande, il y aura un champ d'information d'en-tête Origin . La réponse du serveur aura également un champ d'en-tête d' Access-Control-Allow-Origin .
Vous trouverez ci-dessous la demande CORS normale du navigateur après la demande "Facler".
PUT /cors HTTP/1.1Origin: http://api.bob.comHost: api.alice.comX-Custom-Header: valueAccept-Language: en-USConnection: keep-aliveUser-Agent: Mozilla/5.0...
Le champ Origin des informations d'en-tête ci-dessus est automatiquement ajouté par le navigateur.
Vous trouverez ci-dessous la réponse normale du serveur.
Access-Control-Allow-Origin: http://api.bob.comContent-Type: text/html; charset=utf-8
Dans les informations d'en-tête ci-dessus, le champ Access-Control-Allow-Origin doit être inclus dans chaque réponse.
5. Comparaison avec JSONP
CORS est utilisé dans le même but que JSONP, mais il est plus puissant que JSONP.
JSONP ne prend en charge que les demandes GET , CORS prend en charge tous les types de demandes HTTP. L'avantage de JSONP est qu'il prend en charge les navigateurs à l'ancienne et peut demander des données sur des sites Web qui ne prennent pas en charge les COR.
(sur)