Cross-Origin Resource Sharing (CORS)
Baseline
Large disponibilité
Cette fonctionnalité est bien établie et fonctionne sur de nombreux appareils et versions de navigateurs. Elle est disponible sur tous les navigateurs depuis juillet 2015.
Le Cross-Origin Resource Sharing (CORS) (ou « partage des ressources entre origines multiples » en français, moins usité) est un mécanisme basé sur les en-têtes HTTP qui permet à un serveur d'indiquer toute origine (domaine, schéma ou port) autre que la sienne à partir de laquelle un navigateur doit autoriser le chargement des ressources. CORS repose également sur un mécanisme par lequel les navigateurs effectuent une requête « préliminaire » (preflight en anglais) au serveur hébergeant la ressource cross-origin, afin de vérifier que le serveur autorise la requête réelle. Dans cette pré-requête, le navigateur envoie des en-têtes indiquant la méthode HTTP et les en-têtes qui sont utilisés dans la requête réelle.
Par exemple, une requête inter-origine : le code JavaScript côté client servi depuis https://domaine-a.com utilise fetch() pour effectuer une requête vers https://domaine-b.com/data.json.
Pour des raisons de sécurité, les navigateurs restreignent les requêtes HTTP inter-origine initiées par des scripts. Par exemple, fetch() et XMLHttpRequest respectent la politique de même origine. Cela signifie qu'une application web utilisant ces API ne peut demander des ressources qu'à partir de la même origine que celle depuis laquelle l'application a été chargée, sauf si la réponse d'autres origines inclut les bons en-têtes CORS.
Le mécanisme CORS prend en charge des requêtes inter-origine sécurisées et des transferts de données entre navigateurs et serveurs. Les navigateurs utilisent CORS dans des API telles que fetch() ou XMLHttpRequest pour réduire les risques liés aux requêtes HTTP inter-origine.
Quelles requêtes utilisent le CORS ?
Ce standard de partage inter-origine (angl.) peut activer les requêtes HTTP inter-origine pour :
- Les appels à
fetch()ouXMLHttpRequest, comme mentionné ci-dessus. - Les polices web (pour l'utilisation de polices entre domaines dans
@font-faceen CSS), comme décrit dans les exigences de chargement des polices (angl.), afin que les serveurs puissent déployer des polices TrueType qui ne peuvent être chargées qu'en inter-origine et utilisées par les sites web autorisés. - Textures WebGL.
- Images ou images vidéo dessinées sur un canevas avec
drawImage(). - Formes CSS à partir d'images.
Ceci est un article général sur le partage des ressources entre origines multiples et inclut une discussion des en-têtes HTTP nécessaires.
Aperçu fonctionnel
Le standard CORS fonctionne grâce à l'ajout de nouveaux en-têtes HTTP qui permettent aux serveurs de décrire un ensemble d'origines autorisées pour lire l'information depuis un navigateur web. De plus, pour les méthodes de requêtes HTTP qui entraînent des effets de bord sur les données côté serveur (notamment pour les méthodes en dehors de GET ou pour les méthodes POST utilisées avec certains types MIME), la spécification indique que les navigateurs doivent effectuer une requête préliminaire (preflight request en anglais) et demander au serveur les méthodes prises en charges avec une requête utilisant la méthode OPTIONS puis, après approbation du serveur, envoyer la vraie requête. Les serveurs peuvent également indiquer aux clients s'il est nécessaire de fournir des informations d'authentification (que ce soit des cookies ou des données d'authentification HTTP) avec les requêtes.
Les échecs CORS génèrent des erreurs, mais pour des raisons de sécurité, les détails de l'erreur ne sont pas accessibles par JavaScript. Tout ce que le code sait, c'est qu'une erreur s'est produite. La seule façon de déterminer précisément ce qui s'est passé est de consulter la console du navigateur pour obtenir plus de détails.
Les sections qui suivent évoquent les différents scénarios relatifs au CORS ainsi qu'un aperçu des en-têtes HTTP utilisés.
Exemples de scénarios pour le contrôle d'accès
Nous présentons trois scénarios qui illustrent le fonctionnement du partage des ressources entre origines multiples (CORS). Tous ces exemples utilisent fetch(), qui peut effectuer des requêtes entre origines dans n'importe quel navigateur compatible.
Requêtes simples
Certaines requêtes ne déclenchent pas de requête CORS préliminaire. Celles-ci sont appelées requêtes simples dans l'ancienne spécification CORS (angl.), bien que la spécification Fetch (angl.) (qui définit maintenant le CORS) n'utilise pas ce terme.
La motivation est que l'élément <form> de HTML 4.0 (qui précède les requêtes inter-origines avec fetch() et XMLHttpRequest) peut soumettre des requêtes simples à n'importe quelle origine, donc toute personne écrivant un serveur doit déjà se protéger contre les attaques falsification de requête inter-sites (CSRF). Dans cette hypothèse, le serveur n'a pas besoin de s'inscrire (en répondant à une requête préliminaire) pour recevoir toute requête qui ressemble à une soumission de formulaire, puisque la menace de CSRF n'est pas pire que celle d'une soumission de formulaire. Cependant, le serveur doit toujours s'inscrire en utilisant Access-Control-Allow-Origin pour partager la réponse avec le script.
Une requête simple est une requête qui respecte toutes les conditions suivantes :
-
Les seules méthodes autorisées sont :
-
Hormis les en-têtes définis automatiquement par l'agent utilisateur (par exemple,
Connection,User-Agentou les en-têtes de requête interdits), les seuls en-têtes qui peuvent être paramétrés manuellement sont les en-têtes de requête CORS sécurisés, qui sont :AcceptAccept-LanguageContent-LanguageContent-Type(cf. les contraintes supplémentaires ci-après)Range(uniquement avec une valeur d'en-tête de plage unique (angl.) ; par exemple,bytes=256-oubytes=127-255)
-
Les seules combinaisons type/sous-type autorisées pour le type MIME défini dans l'en-tête
Content-Typesont :application/x-www-form-urlencodedmultipart/form-datatext/plain
-
Si la requête est effectuée à l'aide d'un objet
XMLHttpRequest, aucun gestionnaire d'évènements n'est enregistré sur l'objet retourné par la propriétéXMLHttpRequest.uploadutilisée dans la requête ; c'est-à-dire que, étant donné une instancexhrXMLHttpRequest, aucun code n'a appeléxhr.upload.addEventListener()pour ajouter un gestionnaire d'évènements afin de surveiller le téléchargement. -
Aucun objet
ReadableStreamn'est utilisé dans la requête.
Note :
Les aperçus WebKit Nightly et Safari Technology imposent des restrictions supplémentaires sur les valeurs autorisées dans les en-têtes Accept, Accept-Language et Content-Language. Si l'un de ces en-têtes contient des valeurs « non standard », WebKit/Safari ne considère pas la requête comme une « requête simple ». Les valeurs que WebKit/Safari considère comme « non standard » ne sont pas documentées, sauf dans les bogues WebKit suivants :
- Exiger une requête préliminaire pour les en-têtes de requête CORS sécurisés non standard Accept, Accept-Language et Content-Language (angl.)
- Autoriser les virgules dans les en-têtes de requête Accept, Accept-Language et Content-Language pour les requêtes CORS simples (angl.)
- Passer à un modèle de liste noire pour les en-têtes Accept restreints dans les requêtes CORS simples (angl.)
Aucun autre navigateur n'applique ces restrictions supplémentaires, car elles ne font pas partie de la spécification.
Si, par exemple, on a un contenu web situé sous le domaine http://toto.exemple qui souhaite invoquer du contenu situé sous le domaine http://truc.autre, on pourrait utiliser du code JavaScript semblable à ce qui suit sur toto.exemple :
const fetchPromise = fetch("https://truc.autre");
fetchPromise
.then((reponse) => reponse.json())
.then((donnee) => {
console.log(donnee);
});
Cette opération effectue un échange simple entre le client et le serveur, en utilisant les en-têtes CORS pour gérer les privilèges :
Voyons ce que le navigateur va envoyer au serveur dans ce cas :
GET /resources/public-data/ HTTP/1.1
Host: bar.other
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:71.0) Gecko/20100101 Firefox/71.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: fr-FR,fr;q=0.5
Accept-Encoding: gzip,deflate
Connection: keep-alive
Origin: https://toto.exemple
L'en-tête de requête à noter est Origin, qui montre que l'invocation provient de https://toto.exemple.
Voyons maintenant comment le serveur répond :
HTTP/1.1 200 OK
Date: Mon, 01 Dec 2008 00:23:53 GMT
Server: Apache/2
Access-Control-Allow-Origin: *
Keep-Alive: timeout=2, max=100
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: application/xml
[…XML Data…]
En réponse, le serveur retourne un en-tête Access-Control-Allow-Origin avec Access-Control-Allow-Origin: *, ce qui signifie que la ressource peut être accédée par n'importe quelle origine.
Access-Control-Allow-Origin: *
Ce modèle d'utilisation des en-têtes Origin et Access-Control-Allow-Origin est la forme la plus simple du protocole de contrôle d'accès. Si les propriétaires de la ressource sur https://truc.autre souhaitent restreindre l'accès à la ressource aux requêtes uniquement depuis https://toto.exemple (c'est-à-dire qu'aucun autre domaine que https://toto.exemple ne peut accéder à la ressource en inter-origine), ils enverraient :
Access-Control-Allow-Origin: https://toto.exemple
Note :
Lorsqu'il répond à une requête avec informations d'identification, le serveur doit définir une origine dans la valeur de l'en-tête Access-Control-Allow-Origin, au lieu de définir le caractère générique *.
Requêtes préliminaires
Contrairement aux requêtes simples, pour les requêtes « préliminaires », le navigateur envoie d'abord une requête HTTP utilisant la méthode OPTIONS à la ressource sur l'autre origine, afin de déterminer si la requête réelle est sûre à envoyer. Ces requêtes inter-origines sont préliminaires, car elles peuvent avoir des implications pour les données de l'utilisateur·ice.
L'exemple suivant montre une requête qui est préliminaire :
const fetchPromise = fetch("https://truc.autre/doc", {
method: "POST",
mode: "cors",
headers: {
"Content-Type": "text/xml",
"X-PINGOTHER": "pingpong",
},
body: "<person><name>Arun</name></person>",
});
fetchPromise.then((reponse) => {
console.log(reponse.status);
});
La démonstration ci‑dessus crée un corps XML à envoyer avec la requête POST. De plus, un en‑tête HTTP non standard X-PINGOTHER est défini. Ces en‑têtes ne font pas partie de HTTP/1.1, mais sont généralement utiles aux applications web. Comme la requête utilise un Content-Type de text/xml et qu'un en‑tête personnalisé est défini, cette requête est préliminaire.
Note :
Comme décrit ci‑dessous, la requête POST réelle n'inclut pas les en‑têtes Access-Control-Request-* ; ils ne sont nécessaires que pour la requête OPTIONS.
Voyons l'échange complet entre le client et le serveur. Le premier échange est la requête préliminaire/réponse :
OPTIONS /doc HTTP/1.1
Host: truc.autre
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:71.0) Gecko/20100101 Firefox/71.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: fr-FR,fr;q=0.5
Accept-Encoding: gzip,deflate
Connection: keep-alive
Origin: https://toto.exemple
Access-Control-Request-Method: POST
Access-Control-Request-Headers: content-type,x-pingother
HTTP/1.1 204 No Content
Date: Mon, 01 Dec 2008 01:15:39 GMT
Server: Apache/2
Access-Control-Allow-Origin: https://toto.exemple
Access-Control-Allow-Methods: POST, GET, OPTIONS
Access-Control-Allow-Headers: X-PINGOTHER, Content-Type
Access-Control-Max-Age: 86400
Vary: Accept-Encoding, Origin
Keep-Alive: timeout=2, max=100
Connection: Keep-Alive
Le premier bloc ci‑dessus représente la requête préliminaire avec la méthode OPTIONS. Le navigateur détermine qu'il doit l'envoyer en fonction des paramètres de requête utilisés par l'extrait de code JavaScript ci‑dessus, afin que le serveur puisse répondre si l'envoi de la requête réelle avec ces paramètres est acceptable. OPTIONS est une méthode HTTP/1.1 utilisée pour obtenir des informations complémentaires depuis les serveurs et est une méthode sûre, ce qui signifie qu'elle ne peut pas être utilisée pour modifier la ressource. Notez que en plus de la requête OPTIONS, deux autres en‑têtes de requête sont envoyés :
Access-Control-Request-Method: POST
Access-Control-Request-Headers: content-type,x-pingother
L'en‑tête Access-Control-Request-Method informe le serveur, dans le cadre d'une requête préliminaire, que lorsque la requête réelle est envoyée, elle utilise la méthode POST. L'en‑tête Access-Control-Request-Headers informe le serveur que la requête réelle contient les en‑têtes personnalisés X-PINGOTHER et Content-Type. Le serveur peut alors déterminer s'il peut accepter une requête dans ces conditions.
Le second bloc ci‑dessus est la réponse que le serveur retourne, qui indique que la méthode de requête (POST) et les en‑têtes de requête (X-PINGOTHER) sont acceptables. Voyons de plus près les lignes suivantes :
Access-Control-Allow-Origin: https://foo.example
Access-Control-Allow-Methods: POST, GET, OPTIONS
Access-Control-Allow-Headers: X-PINGOTHER, Content-Type
Access-Control-Max-Age: 86400
Le serveur répond avec Access-Control-Allow-Origin: https://foo.example, restreignant l'accès à l'origine requérante uniquement. Il répond également avec Access-Control-Allow-Methods, qui indique que POST et GET sont des méthodes valides pour interroger la ressource concernée (cet en‑tête est similaire à l'en‑tête de réponse Allow, mais utilisé strictement dans le contexte du contrôle d'accès).
Le serveur envoie aussi Access-Control-Allow-Headers avec la valeur X-PINGOTHER, Content-Type, confirmant que ces en‑têtes peuvent être utilisés avec la requête réelle. Comme Access-Control-Allow-Methods, Access-Control-Allow-Headers est une liste d'en‑têtes acceptables, séparée par des virgules.
Enfin, Access-Control-Max-Age donne la durée en secondes pendant laquelle la réponse à la requête préliminaire peut être mise en cache sans envoyer une autre requête préliminaire. La valeur par défaut est de 5 secondes. Dans le présent cas, la durée maximale est de 86400 secondes (= 24 heures). Notez que chaque navigateur a une valeur interne maximale qui prévaut lorsque la valeur Access-Control-Max-Age la dépasse.
Une fois la requête préliminaire terminée, la requête réelle est envoyée :
POST /doc HTTP/1.1
Host: truc.autre
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:71.0) Gecko/20100101 Firefox/71.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: fr-FR,fr;q=0.5
Accept-Encoding: gzip,deflate
Connection: keep-alive
X-PINGOTHER: pingpong
Content-Type: text/xml; charset=UTF-8
Referer: https://toto.exemple/exemples/preflightInvocation.html
Content-Length: 55
Origin: https://toto.exemple
Pragma: no-cache
Cache-Control: no-cache
<person><name>Arun</name></person>
HTTP/1.1 200 OK
Date: Mon, 01 Dec 2008 01:15:40 GMT
Server: Apache/2
Access-Control-Allow-Origin: https://toto.exemple
Vary: Accept-Encoding, Origin
Content-Encoding: gzip
Content-Length: 235
Keep-Alive: timeout=2, max=99
Connection: Keep-Alive
Content-Type: text/plain
[Du contenu XML]
Requêtes préliminaires et redirection
Tous les navigateurs ne prennent pas encore en charge le suivi des redirections après une requête préliminaire. Si une redirection se produit après une telle requête, certains navigateurs affichent actuellement un message d'erreur tel que le suivant :
La requête a été redirigée vers
https://exemple.com/toto, ce qui est interdit pour les requêtes inter-origines nécessitant une prévalidation. La requête nécessite une prévalidation, ce qui est interdit pour suivre les redirections inter-origines.
Le protocole CORS exigeait initialement ce comportement mais a depuis été modifié pour ne plus l'exiger (angl.). Toutefois, tous les navigateurs n'ont pas encore implémenté ce changement et conservent donc le comportement initial.
Tant que les navigateurs ne se sont pas alignés sur la spécification, vous pouvez contourner cette limitation en faisant une ou les deux actions suivantes :
- Modifier le comportement côté serveur pour éviter la requête préliminaire et/ou pour éviter la redirection — Modifier la requête afin qu'il s'agisse d'une requête simple qui n'entraîne pas de prévalidation
Si cela n'est pas possible, une autre solution consiste à :
- Effectuer une requête simple (en utilisant
Response.urlpour l'API Fetch, ouXMLHttpRequest.responseURL) pour déterminer vers quelle URL la requête prévalidée réelle aboutirait. - Faire une autre requête (la requête réelle) en utilisant l'URL obtenue depuis
Response.urlouXMLHttpRequest.responseURLlors de la première étape.
Cependant, si la requête déclenche une prévalidation à cause de la présence de l'en-tête Authorization, vous ne pouvez pas contourner la limitation avec les étapes ci‑dessus. Et vous ne pouvez pas du tout la contourner à moins de contrôler le serveur vers lequel la requête est effectuée.
Requêtes avec informations d'authentification
Note : Lorsque vous effectuez des requêtes authentifiées vers un autre domaine, les politiques relatives aux cookies tiers s'appliquent toujours. La politique s'applique indépendamment de toute configuration côté serveur ou côté client décrite dans ce chapitre.
La fonctionnalité la plus intéressante exposée à la fois par fetch() ou XMLHttpRequest et CORS est la possibilité d'effectuer des requêtes « authentifiées » qui tiennent compte des cookies HTTP et des informations d'authentification HTTP. Par défaut, lors d'appels inter-origine avec fetch() ou XMLHttpRequest, les navigateurs n'envoient pas les informations d'authentification.
Pour demander qu'une requête fetch() inclue les informations d'authentification, définir l'option credentials sur "include".
Pour demander qu'une requête XMLHttpRequest inclue les informations d'authentification, définir la propriété XMLHttpRequest.withCredentials à true.
Dans cet exemple, un contenu initialement chargé depuis https://toto.exemple effectue une requête GET vers une ressource située sur https://truc.autre qui définit des cookies. Le contenu sur toto.exemple peut contenir le code JavaScript suivant :
const url = "https://truc.autre/resources/credentialed-content/";
const requete = new Request(url, { credentials: "include" });
const fetchPromise = fetch(requete);
fetchPromise.then((reponse) => console.log(reponse));
Ce code crée un objet Request en définissant l'option credentials sur "include" dans le constructeur, puis transmet cet objet à fetch(). Comme il s'agit d'une requête GET simple, elle n'est pas prévalidée, mais le navigateur rejette toute réponse qui ne possède pas l'en-tête Access-Control-Allow-Credentials défini à true, et ne rend pas la réponse disponible pour le contenu web qui a effectué l'appel.
Voici un exemple d'échange entre le client et le serveur :
GET /resources/credentialed-content/ HTTP/1.1
Host: truc.autre
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:71.0) Gecko/20100101 Firefox/71.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: fr-FR,fr;q=0.5
Accept-Encoding: gzip,deflate
Connection: keep-alive
Referer: https://toto.exemple/exemples/credential.html
Origin: https://toto.exemple
Cookie: pageAccess=2
HTTP/1.1 200 OK
Date: Mon, 01 Dec 2008 01:34:52 GMT
Server: Apache/2
Access-Control-Allow-Origin: https://toto.exemple
Access-Control-Allow-Credentials: true
Cache-Control: no-cache
Pragma: no-cache
Set-Cookie: pageAccess=3; expires=Wed, 31-Dec-2008 01:34:53 GMT
Vary: Accept-Encoding, Origin
Content-Encoding: gzip
Content-Length: 106
Keep-Alive: timeout=2, max=100
Connection: Keep-Alive
Content-Type: text/plain
[contenu text/plain]
Bien que l'en-tête Cookie de la requête contienne le cookie destiné au contenu de https://truc.autre, si truc.autre ne répond pas avec un Access-Control-Allow-Credentials avec la valeur true, comme le montre cet exemple, la réponse est ignorée et n'est pas mise à la disposition du contenu web.
Requêtes préliminaires et informations d'authentification
Les requêtes de prévalidation CORS ne doivent jamais inclure d'informations d'authentification. La réponse à une requête préliminaire doit préciser Access-Control-Allow-Credentials: true pour indiquer que la requête réelle peut être effectuée avec des informations d'authentification.
Note : Certains services d'authentification d'entreprise exigent que des certificats clients TLS soient envoyés dans les requêtes de prévalidation, en contradiction avec la spécification Fetch (angl.).
Firefox 87 permet d'activer ce comportement non conforme en définissant la préférence : network.cors_preflight.allow_client_cert sur true bogue Firefox 1511151 (angl.). Les navigateurs basés sur Chromium envoient actuellement toujours des certificats client TLS dans les requêtes de pré-vérification CORS bogue Chrome 775438 (angl.).
Requêtes authentifiées et jokers (wildcards)
Lors de la réponse à une requête avec informations d'authentification :
- Le serveur ne doit pas définir le caractère générique
*pour la valeur de l'en-tête de réponseAccess-Control-Allow-Origin, mais doit au contraire indiquer une origine explicite ; par exemple,Access-Control-Allow-Origin: https://exemple.com - Le serveur ne doit pas définir le caractère générique
*pour la valeur de l'en-tête de réponseAccess-Control-Allow-Headers, mais doit au contraire indiquer une liste explicite de noms d'en-têtes ; par exemple,Access-Control-Allow-Headers: X-PINGOTHER, Content-Type - Le serveur ne doit pas définir le caractère générique
*pour la valeur de l'en-tête de réponseAccess-Control-Allow-Methods, mais doit au contraire indiquer une liste explicite de noms de méthodes ; par exemple,Access-Control-Allow-Methods: POST, GET - Le serveur ne doit pas définir le caractère générique
*pour la valeur de l'en-tête de réponseAccess-Control-Expose-Headers, mais doit au contraire indiquer une liste explicite de noms d'en-têtes ; par exemple,Access-Control-Expose-Headers: Content-Encoding, Kuma-Revision
Si une requête inclut des informations d'authentification (le plus souvent l'en‑tête Cookie) et que la réponse contient un en‑tête Access-Control-Allow-Origin: * (c'est‑à‑dire avec le joker), le navigateur bloque l'accès à la réponse et affiche une erreur CORS dans la console des outils de développement.
En revanche, si une requête inclut des informations d'authentification (comme l'en‑tête Cookie) et que la réponse contient une origine réelle plutôt que le joker (par exemple Access-Control-Allow-Origin: https://exemple.com), alors le navigateur autorise l'accès à la réponse depuis l'origine définie.
Notez aussi qu'un en‑tête de réponse Set-Cookie ne définit pas de cookie si la valeur de Access-Control-Allow-Origin dans cette réponse est le joker * plutôt qu'une origine réelle.
Cookies tiers
Notez que les cookies définis dans les réponses CORS sont soumis aux politiques normales de cookies tiers. Dans l'exemple ci-dessus, la page est chargée depuis toto.exemple, mais l'en-tête Set-Cookie dans la réponse est envoyé par truc.autre, et ne serait donc pas enregistré si le navigateur de l'utilisateur·ice est configuré pour rejeter tous les cookies tiers.
Les cookies définis dans les requêtes et réponses CORS sont soumis aux mêmes politiques de cookies tiers.
Les politiques de cookies tiers peuvent empêcher l'envoi de cookies tiers dans les requêtes, ce qui empêche effectivement un site de faire des requêtes authentifiées même si le serveur tiers le permet (en utilisant Access-Control-Allow-Credentials). La politique par défaut diffère selon les navigateurs, mais peut être définie à l'aide de l'attribut SameSite.
Même si les requêtes authentifiées sont autorisées, un navigateur peut être configuré pour rejeter tous les cookies tiers présents dans les réponses.
En-têtes de réponse HTTP
Dans cette section, on liste les en-têtes de réponse HTTP qui sont renvoyés par le serveur pour le contrôle d'accès, tels que définis par la spécification Cross-Origin Resource Sharing. La section précédente illustre, avec des exemples concrets, leur fonctionnement.
Access-Control-Allow-Origin
Une ressource retournée peut comporter un en‑tête Access-Control-Allow-Origin avec la syntaxe suivante :
Access-Control-Allow-Origin: <origin> | *
Access-Control-Allow-Origin indique soit une origine unique autorisée à accéder à la ressource ; soit — pour les requêtes sans informations d'authentification — le joker * indique aux navigateurs d'autoriser n'importe quelle origine à accéder à la ressource.
Par exemple, pour autoriser du code provenant de l'origine https://mozilla.org à accéder à la ressource, vous pouvez définir :
Access-Control-Allow-Origin: https://mozilla.org
Vary: Origin
Si le serveur indique une origine unique (qui peut varier dynamiquement en fonction de l'origine requérante dans le cadre d'une liste d'autorisations) plutôt que le joker *, le serveur doit également inclure Origin dans l'en‑tête de réponse Vary pour indiquer aux clients que les réponses du serveur varient selon la valeur de l'en‑tête de requête Origin.
Access-Control-Expose-Headers
L'en-tête Access-Control-Expose-Headers ajoute les en-têtes définis à la liste blanche que JavaScript (comme Response.headers) dans les navigateurs est autorisé à accéder.
Access-Control-Expose-Headers: <header-name>[, <header-name>]*
Par exemple, ce qui suit permet aux en-têtes X-My-Custom-Header et X-Another-Custom-Header d'être exposés au navigateur :
Access-Control-Expose-Headers: X-My-Custom-Header, X-Another-Custom-Header
Access-Control-Max-Age
L'en-tête Access-Control-Max-Age indique la durée pendant laquelle le résultat de la requête préliminaire peut être mis en cache. Pour un exemple de requête préliminaire, voir les exemples ci-dessus.
Access-Control-Max-Age: <delta-en-secondes>
Le paramètre delta-en-secondes indique le nombre de secondes pendant lesquelles les résultats peuvent être mis en cache.
Access-Control-Allow-Credentials
L'en-tête Access-Control-Allow-Credentials indique si la réponse à la requête peut être exposée lorsque l'option credentials est définie sur true. Lorsqu'il est utilisé dans le cadre d'une réponse à une requête de pré-vérification, il indique si la requête proprement dite peut être effectuée à l'aide d'identifiants. Notez que les simples requêtes GET ne font pas l'objet d'un contrôle préalable, et donc si une requête est effectuée pour une ressource avec des identifiants, si cet en-tête n'est pas retourné avec la ressource, la réponse est ignorée par le navigateur et n'est pas retournée au contenu web.
Access-Control-Allow-Credentials: true
Requêtes avec informations d'authentification sont discutées ci-dessus.
Access-Control-Allow-Methods
L'en‑tête Access-Control-Allow-Methods indique la ou les méthodes autorisées pour accéder à la ressource. Cet en‑tête est utilisé en réponse à une requête préliminaire. Les conditions dans lesquelles une requête fait l'objet d'une prévalidation sont expliquées ci‑dessus.
Access-Control-Allow-Methods: <method>[, <method>]*
Un exemple de requête préliminaire est donné ci‑dessus, incluant un exemple qui envoie cet en‑tête au navigateur.
Access-Control-Allow-Headers
L'en‑tête Access-Control-Allow-Headers est utilisé en réponse à une requête préliminaire pour indiquer quels en‑têtes HTTP peuvent être utilisés lors de l'envoi de la requête réelle. Cet en‑tête est la réponse côté serveur à l'en‑tête Access-Control-Request-Headers du navigateur.
Access-Control-Allow-Headers: <header-name>[, <header-name>]*
En-têtes de requête HTTP
Cette section décrit les en-têtes que les clients peuvent utiliser lors de l'envoi de requêtes HTTP afin d'exploiter les fonctionnalités du partage entre origines. Notez que ces en-têtes sont automatiquement définis lors des appels aux serveurs. Les développeur·euse·s effectuant des requêtes multi-origines n'ont pas besoin de définir ces en-têtes de partage entre origines de manière programmatique.
Origin
L'en‑tête Origin indique l'origine de la requête d'accès inter‑origine ou de la requête préliminaire.
Origin: <origin>
L'origine est une URL indiquant le serveur depuis lequel la requête est initiée. Elle n'inclut aucune information de chemin, uniquement le nom du serveur.
Note :
La valeur origin peut être null.
Notez que, dans toute requête de contrôle d'accès, l'en‑tête Origin est toujours envoyé.
Access-Control-Request-Method
L'en‑tête Access-Control-Request-Method est utilisé lors de l'envoi d'une requête préliminaire afin d'informer le serveur de la méthode HTTP qui est utilisée quand la requête réelle est effectuée.
Access-Control-Request-Method: <method>
Des exemples d'utilisation se trouvent ci‑dessus.
Access-Control-Request-Headers
L'en‑tête Access-Control-Request-Headers est utilisé lors de l'envoi d'une requête préliminaire pour indiquer au serveur quels en‑têtes HTTP sont utilisés lors de la requête réelle (par exemple, en les passant par l'option headers). Cet en‑tête côté client reçoit une réponse correspondante côté serveur dans l'en‑tête Access-Control-Allow-Headers.
Access-Control-Request-Headers: <field-name>[,<field-name>]*
Des exemples d'utilisation se trouvent ci‑dessus.
Spécifications
| Spécification |
|---|
| Fetch> # http-access-control-allow-origin> |
Compatibilité des navigateurs
Voir aussi
- Les erreurs CORS
- Activer CORS : je veux ajouter la prise en charge de CORS à mon serveur (angl.)
- L'API Fetch
- L'interface API
XMLHttpRequest - Est-ce que ça fonctionne avec CORS ? (angl.) — un guide interactif et un générateur sur le CORS
- Comment utiliser le navigateur Chrome sans CORS (angl.)
- Utiliser le CORS avec tous les navigateurs (modernes) (angl.)
- Réponse sur Stack Overflow avec des « comment faire » pour résoudre les problèmes courants (angl.) :
- Comment éviter les requêtes préliminaires
- Comment utiliser un proxy CORS pour contourner « No Access-Control-Allow-Origin header »
- Comment corriger « Access-Control-Allow-Origin header must not be the wildcard »