Le requêtes cross domaine faciles avec le formation JSONP (JSON with Padding)
Si vous faites des applications Javascript modernes, et requêtez avec la fonction fetch(), vous êtes sans doute confronté à des problèmes de CORS (Cross Origin Request Forgery), en clair vous faites une requête AJAX depuis une nom de domaine différent du nom de domaine du webservice.
Le CORS est une feature et pas un bug : Par exemple, avec le site OpenWeatherMap.org, vous pouvez requêter des données météo depuis votre ordinateur local, qui a un nom de host forcément différent de OpenWeatherMap.org. On fait du CORS. Mais parfois c’est un peu délicat, notamment beaucoup n’ont pas les connaissances théoriques sous jacentes. ça peut devenir compliqué, surtout avec le requêtes PREFLIGHT qui consistent à envoyer un pré-requête pour « tester » la température de l’eau.
Mais le JSONP peut nous être utile, on va voir comment.
Le principe du JSONP
Le JSONP n’est pas une forme de JSON, c’est du JSON, mais utilisé de façon astucieuse en conjonction entre le serveur et le navigateur.
Un exemple simple de JSONP
Le fichier front end jsonpfront.php :
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>JSON P</title>
</head>
<body>
<div id="demo"></div>
</body>
<script>
function myFunc(myObj) {
document.getElementById("demo").innerHTML = myObj.name;
}
</script>
<script src="jsonp.php"></script>
</html>
Le fichier back jsonp.php.
<?php
$myJSON = '{ "name":"John", "age":30, "city":"New York" }';
echo "myFunc(".$myJSON.");";
?>
La balise script du front inclut le fichier du back jsonp.php, Ce fichier s’il est exécuté, revoit un réponse texte myFunc({ « name »: »John », « age »:30, « city »: »New York » })
myFunc est définie plus haut dans le script du front, donc en fait elle va être exécutée au moment du chargement de la page.
Un exemple plus intéressant dynamique de JSONP
Ok on a vu que ça marchait, mais c’est un peu statique tout ça, par exemple le snippet d’inclusion du est statique, on va le rendre dynamique, après tout lorsque qu’on fait une requête AJAX c’est souvent sur demande de l’utilisateur non?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>JSON P</title>
</head>
<body>
<div id="demo"></div>
<a href=# onclick="clickButton();">Click</a>
</body>
<script>
function myFunc(myObj) {
document.getElementById("demo").innerHTML = myObj.name;
}
function clickButton() {
let s = document.createElement("script");
s.src = "jsonp.php?x=Yvon";
document.body.appendChild(s);
}
</script>
</html>
Il faut cliquer sur le bouton pour inclure à la demande le fichier jsonp.php.
Et le nouveau fichier du backend, qui renvoit un content-type application/json, comme une vraie réponse AJAX du serveur. De plus on passe au fichier du backend un paramètre GET, pour simuler une demande d’une information particulière (par exemple les informations d’un utilisateur.). On simule succinctement une requêtes à la base de données en fait.
<?php
header("Content-Type: application/json; charset=UTF-8");
$obj = json_decode($_GET["x"], false);
$outp = ["name" => $_GET["x"], "age" => 30, "city" => "New York"];
echo "myFunc(" . json_encode($outp) . ")";
Ok ça marche aussi ! La réponse du serveur est à la demande, comme une requête de type GET.
Quid du cross domaine?
Je vous avait promis du cross domaine au début voyons voir comment ! C’est tout simple on va dans le fichier front modifier le endpoint de fichier jsonp.php, et mettre ce dernier sur un serveur sur Internet. Mon front sera toujours en local, donc on est bien en situation de cross domaine.
function clickButton() {
let s = document.createElement("script");
s.src = "http://glottr.com/jsonp.php?x=Yvon";
document.body.appendChild(s);
}
C’est là que c’est intéressant. Vous voyez comment on peut inclure le fichier jsonp.php ? C’est dans la balise <script> et dans ce cas, on peut inclure un script de n’importe quel domaine.
Bougeons le fichier et regardons, le résultat est le même !
On peut faire plus sophistiqué avec JSONP
Jusqu’ici la fonction myFunc était codée dans le serveur, comment ferait on si on ne sait pas à l’avance la fonction à invoquer côté client? Vous pouvez passer le nom de la fonction callback en paramètre GET
Comment ferait on en AJAX?











