Dynamic Script Loading

L'un des chapitres précédents a mis en lumière un des fondements de l'AJAX : l'objetXMLHttpRequest. Mais il n'a pas fallu attendre cet objet pour avoir la possibilité de dialoguer avec un serveur, comme nous allons le voir ici !

Au cours de ce chapitre vous allez découvrir une manière astucieuse de dialoguer avec un serveur. Elle possède un avantage considérable face à l'objetXMLHttpRequest: elle n'est en aucun cas limitée par le principe de la same origin policy !

Un concept simple

Avec le DOM, il est possible d'insérer n'importe quel élément HTML au sein d'une page Web, et cela vaut également pour un élément<script>. Il est donc possible de lier et d'exécuter un fichier JavaScript après que la page a été chargée :

window.addEventListener('load', function() {
var scriptElement = document.createElement('script');
scriptElement.src = 'url/du/fichier.js';
document.body.appendChild(scriptElement);
});

Avec ce code, un nouvel élément<script>sera inséré dans la page une fois que cette dernière aura été chargée. Mais s'il est possible de charger un fichier JavaScript à la demande, pourquoi ne pas s'en servir pour charger des données, et « faire de l'AJAX » ?

Un premier exemple

Nous allons commencer par quelque chose de très simple : dans une page HTML, on va charger un fichier JavaScript qui exécutera une fonction. Cette fonction se trouve dans la page HTML.

<script>
function sendDSL() {
var scriptElement = document.createElement('script');
scriptElement.src = 'dsl_script.js';
document.body.appendChild(scriptElement);
}
function receiveMessage(message) {
alert(message);
}
</script>
<p><button type="button" onclick="sendDSL()">Exécuter le script</button></p>

Essayer le code

Voici maintenant le contenu du fichierdsl_script.js:

receiveMessage('Ce message est envoyé par le serveur !');

Décortiquons tout cela. Dès qu'on clique sur le bouton, la fonctionsendDSL()va charger le fichier JavaScript qui contient un appel vers la fonctionreceiveMessage(), tout en prenant soin de lui passer un message en paramètre. Ainsi, via la fonctionreceiveMessage(), on est en mesure de récupérer du contenu. Évidemment, cet exemple n'est pas très intéressant puisque l'on sait à l'avance ce que le fichier JavaScript va renvoyer. Ce que nous allons faire, c'est créer le fichier JavaScript via du PHP !

Avec des variables et du PHP

Maintenant, au lieu d'appeler un fichier JavaScript, nous allons appeler une page PHP. Si on reprend le code donné précédemment, on peut modifier l'URL du fichier JavaScript :

scriptElement.src = 'dsl_script.php?nick=' + prompt('Quel est votre pseudo ?');

En ce qui concerne le fichier PHP, il va falloir utiliser la fonctionheader()pour indiquer au navigateur que le contenu du fichier PHP est en réalité du JavaScript.
Puis, il ne reste plus qu'à introduire la variable$_GET['nick']au sein du script JavaScript :

<?php header("Content-type: text/javascript"); ?>
var string = 'Bonjour <?php echo $_GET['nick'] ?> !';
receiveMessage(string);

Essayer le code complet

Et voilà ! Maintenant, si on teste le tout, on constate que le script retourne bien le pseudo que l'utilisateur a entré.

Le DSL et le format JSON

Le gros avantage du Dynamic Script Loading (pour « chargement dynamique de script », abrégé DSL) est qu'il permet de récupérer du contenu sous forme d'objets JavaScript, comme un tableau ou tout simplement un objet littéral, et donc le fameux JSON. Si on récupère des données JSON viaXMLHttpRequest, ces données sont livrées sous la forme de texte brut (récupérées via la propriétéresponseText). Il faut donc utiliser la méthodeparse()de l'objetJSONpour pouvoir les interpréter. Avec le DSL, ce petit souci n'existe pas puisque c'est du JavaScript qui est transmis, et non du texte !

Charger du JSON

Comme dans l'exemple précédent, nous allons utiliser une page PHP pour générer le contenu du fichier JavaScript, et donc notre JSON. Les données JSON contiennent une liste d'éditeurs et pour chacun une liste de programmes qu'ils éditent :

<?php
header("Content-type: text/javascript");
echo 'var softwares = {
"Adobe": [
"Acrobat",
"Dreamweaver",
"Photoshop",
"Flash"
],
"Mozilla": [
"Firefox",
"Thunderbird",
"Lightning"
],
"Microsoft": [
"Office",
"Visual C# Express",
"Azure"
]
};';
?>
receiveMessage(softwares);

Au niveau de la page HTML, pas de gros changements… Nous allons juste coder une meilleure fonctionreceiveMessage()de manière à afficher, dans une alerte, les données issues du JSON. On utilise une bouclefor inpour parcourir le tableau associatif, et une deuxième boucleforimbriquée pour chaque tableau :

<script>
function sendDSL() {
var scriptElement = document.createElement('script');
scriptElement.src = 'dsl_script_json.php';
document.body.appendChild(scriptElement);
}
function receiveMessage(json) {
var tree = '',
nbItems, i;
for (node in json) {
tree += node + "\n";
nbItems = json[node].length;
for (i = 0; i < nbItems; i++) {
tree += '\t' + json[node][i] + '\n';
}
}
alert(tree);
}
</script>
<p><button type="button" onclick="sendDSL()">Charger le JSON</button></p>

Essayer le code complet

Avec ça, pas besoin de parser le JSON, c'est directement opérationnel ! Cette notion est souvent désignée par l'abbréviation JSONP .

Petite astuce pour le PHP

Le PHP dispose de deux fonctions pour manipuler du JSON : json_encode()
et json_decode()
. La première,json_encode(), permet de convertir une variable (un tableau associatif par exemple) en une chaîne de caractères au format JSON. La deuxième,json_decode(), fait le contraire : elle recrée une variable à partir d'une chaîne de caractères au format JSON. Ça peut être utile dans le cas de manipulation de JSON avec du PHP !

En résumé
  • Il est possible de charger un fichier .js en ajoutant un élément<script>via le JavaScript. On appelle cela le Dynamic Script Loading.

  • Cette technique est particulièrement efficace pour charger des données au format JSON.

  • Comme pour les iframes vues précédemment, il faut utiliser un système de callback pour transmettre les données une fois le fichier JavaScript chargé.