HTTP CORS
#1
A quoi sert CORS ?
CORS veut dire Cross Origin Ressource Sharing. En français ça peut se traduire par "partage de ressource entre origines multiples". Le mot important ici c'est origine. On va voir tout de suite ce que c'est que l'origine.
Lorsque le navigateur charge une page web elle lui est servie par un serveur. Il la récupère en donnant notamment trois informations : le protocole / le nom de domaine / le port. Alors il ne donne pas que ça mais ce sont ces trois informations qui constituent l'origine de la page web. Déjà il faut préciser une chose c'est que deux origines sont identiques si les trois informations sont identiques.
Ensuite cette page web lorsque elle se charge sur le navigateur elle va demander des ressources. Pour demander une ressource c'est pareil le navigateur utilise un protocole, un nom de domaine et un port. Deux situations peuvent se présenter :
- La ressource demandée a la même origine que la page web. On dit que l'on est dans le cas Same Origin. Ce n'est pas le cas qui nous intéresse.
- La ressource demandée n'a pas la même origine que la page web. On dit que l'on est dans le cas Cross Origin. On veut pouvoir utiliser des ressources qui ont une origine différente. Et dans ce cas si c'est une requête
XMLHttpRequest
ou une requêtefetch
qui demande la ressource et bien cette dernière par défaut ne sera pas servie. Il faudra faire appel au protocole CORS pour débloquer la situation.

Ce que j'ai appelé le protocole CORS (c'est pas vraiment un protocole) en fait c'est un ensemble d'en-têtes HTTP utilisé par les requêtes HTTP qui sont échangées entre le navigateur et le serveur. Ces en-têtes vont permettre d'autoriser l'accès à des ressources d'origine différente.
Donc vous allez entendre parler de CORS lorsque votre navigateur est bloqué sur l'accès à une ressource. Ca se produit par exemple lorsque vous travaillez en localhost avec un framework sur une machine de dev et que vous faite des requêtes fetch
vers votre Api Rest qui elle se trouve sur une machine de prod. Ca se produit aussi si vous partagez des ressources entre un domaine et un sous-domaine. C'est considéré comme des domaines différents.
#2
Un exemple avec un fetch.
Je vais faire un exemple concret 😎. Je vais regarder ce qui se passe si je fais une requête fetch
depuis une page servie par localhost
par exemple en utilisant le plugin Live Server depuis l'éditeur Visual Studio Code. Je vais faire cette requête fetch
vers une page PHP qui se trouve sur le domaine https://www.devenir-webmaster.com
.
A priori je ne prends aucune précaution particulière.
- Le script que va lancer Live Server c'est le script ci-dessous. Si vous voulez faire la manip vous copier / coller le code ci-dessous dans VSCode.
- Le code PHP qui est installé sur le domaine
www.devenir-webmaster.com
est ci-dessous. Je me contente de renvoyer une en-têteContent-Type
et de répondre aufetch
par unecho
. Ce code est à votre disposition si vous voulez faire le tuto. -
Ensuite je lance mon script avec Live Server.
- La page
fetch-1.html
est servie par un serveur local interne au plugin Live Server à l'adresse127.0.0.1
sur le port5500
et en utilisant le protocoleHTTP
. - La page
fetch-1.html
fait une requête pour charger la ressourceserveur-1.php
sur le domainewww.devenir-webmaster.com
et sur le port443
(port par défaut) et en utilisant le protocoleHTTPS
.
Requête Cross Origin (sans précaution) - La page
-
On peut noter que si je lance le même script mais que cette fois ci je charge ma page
Tester le codefetch-1.html
directement depuis le serveur qui hébergewww.devenir-webmaster.com
. Et bien cette fois ci le serveur accepte ma requête et répondOK
. Pourquoi ? Et bien parce que là je me place dans un cas Same Origin.Requête Same Origin
Si je résume :
-
Dans le premier cas la page
fetch-1.html
est servie parhttp://127.0.0.1:5500
et la ressource se trouve surhttps://www.devenir-webmaster.com
. L'origine de la page et celle de la ressource ne sont pas les mêmes. On se trouve dans le cas Cross Origin et le serveur ne répond pas à la requête. C'est la configuration CORS qui bloque. Il va falloir que le navigateur envoie des en-têtes CORS et que le serveur réponde par d'autres en-têtes CORS pour déverrouiller la situation. -
Dans le deuxième cas la page
fetch-1.html
est servie parhttps://www.devenir-webmaster.com
(port 443) et la ressource se trouve surhttps://www.devenir-webmaster.com
(port 443). L'origine de la page et de la ressource sont les mêmes. On se trouve dans le cas Same Origin et le serveur répond à la requête. Dans ce cas là CORS ne sert à rien !!

#3
Mettre en oeuvre CORS.
Ci-dessous je vais faire ce qu'il faut au niveau de CORS pour pouvoir accéder à la ressource et faire sauter le verrou qui nous bloque.
- Côté navigateur au niveau du
fetch
je vais demander du CORS en mettant{mode : cors}
comme deuxième paramètre defetch
. Je pense que lemode : cors
est activé par défaut avecfetch
mais mieux vaut le demander de manière explicite au moins on est sûr. - Côté serveur au niveau PHP je vais ajouter l'en tête
Access-Control-Allow-Origin
. Je vais mettre une étoile comme valeur ce qui autorise toutes les origines. - Ensuite je reprends Live Server pour lancer ce script. Donc on est dans une configuration Cross Origin.

On constate que le serveur répond à la requête. CORS ici est mis en oeuvre correctement.
#4
Autre cas de figure. Le prefligth.
Maintenant j'enlève l'en-tête Access-Control-Allow-Origin
côté serveur. Je regarde ce qui se passe si je fais une requête autre qu'un GET
ou qu'un POST
par exemple un DELETE
. Le but c'est de voir apparaître un autre message d'erreur et c'est pour cette raison que je vous montre ça.
Je lance ce script avec Live Server et je constate que dans la réponse c'est une preflight request
qui est refusée. En fait dans ce cas le protocole CORS fait une requête pour demander au serveur quelles sont les autorisations. Je vous cite simplement ce cas de figure pour que vous puissiez l'identifier. Je ne vais pas plus loin.

