Robloche nous propose ici un tutorial passionnant sur l'utilisation des requêtes serveur en JavaScript. Ce tutorial a été remis à jour en aout 2017 pour tenir compte des évolutions des navigateurs.
L'objet XMLHTTPRequest permet de réaliser des appels au serveur depuis la page HTML. Il s'agit d'appels AJAX (Asynchronous JAvascript XML).
Aujourd'hui, tous les navigateurs acceptent ce mode de fonctionnement, sans incompatiblité particulière.
AJAX a permis l'émergence de véritables applications web et a grandement participé à l'essor du javascript, qui est même devenu un langage serveur avec Node.js !
Accès rapide aux sections
Comme leur nom ne l'indique pas, les objets XMLHTTPRequest permettent de récupérer toutes sortes de données, et pas seulement des fichiers XML. Pour effectuer une requête, il faut tout d'abord déclarer une certaine variable. Ensuite, on envoie la requête et enfin, on attend la réponse. Ci-après, vous pouvez voir un exemple très basique faisant une requête sur la présente page (location.href). Une fois la réponse obtenue, une boîte d'alerte s'affiche.
> Masquer le code JavaScriptComment ça marche ?
Note : Ces fonctions sont détaillées en section 6.
Dans l'exemple précédent, la requête se contente de demander un certain fichier sans s'occuper du résultat. Mais en fait, lorsque la requête se termine, on reçoit (et heureusement) des informations du serveur. Ces informations sont contenues dans la variable xhr_object.response. Remplaçons simplement l'alerte de l'exemple précédent par alert(xhr_object.response) (cf. ligne 5) et voyons le résultat :
Comme vous l'avez constaté, c'est tout le code de la présente page HTML qui s'est affiché (ça a d'ailleurs dû sortir de l'écran, désolé). En fait, lors d'une telle requête, tout se passe exactement comme si vous aviez tapé l'URL dans la barre d'adresse de votre navigateur. Ce qui signifie que si vous demandez un fichier PHP, il sera exécuté et c'est le résultat de son exécution qui se retrouvera dans xhr_object.response. À partir de là, on se rend vite compte qu'il n'y a pas de limite à l'utilisation de ce type de requête. On peut simplement afficher le résultat reçu avec un alert. On peut mettre le résultat dans un DIV (ou tout autre conteneur HTML), mais on peut tout aussi bien récupérer et exécuter du code JS grâce à eval.
Note : La section 5 présente un exemple concret d'utilisation.
Dans les exemples que nous avons vus jusqu'à maintenant, c'est le mode synchrone qui était utilisé. Cela signifie que tant que le résultat de la requête ne nous est pas parvenu, le script est en pause et le navigateur bloqué. Avec un bon débit et/ou peu de données à transmettre, on pourrait s'en contenter mais cela peut vite s'avérer gênant pour l'utilisateur qui voit son navigateur figé. Ce mode de transmission est donc à proscrire. Heureusement, il existe le mode asynchrone. Dans ce mode, après avoir envoyé la requête via send, le script poursuit son exécution, sans bloquer le navigateur. Évidemment, dans ce mode, il faut prévoir quelque chose pour nous prévenir quand la requête a abouti. C'est le rôle de la fonction onreadystatechange (en fait, onreadystatechange est une propriété et non une fonction, mais comme on lui affecte un pointeur vers une fonction nous pouvons nous permettre cet abus de langage). Prenons comme nouvel exemple une requête sur un simple fichier texte :
> Masquer le code JavaScriptComment ça marche ?
C'est le troisième argument de la fonction open (cf. ligne 3) qui spécifie que le mode doit être asynchrone.
L'objet xhr_object possède une propriété readyState (cf. ligne 6) qui prend successivement 5 valeurs récapitulées dans le tableau suivant :
Et lors de chaque changement d'état de readyState, la fonction onreadystatechange (cf. ligne 6) est appelée. On peut ainsi lui faire faire ce que l'on veut en fonction de l'avancement de la requête. Mais de toute manière, c'est l'état 4 qui nous intéresse et il est généralement très rapidement atteint. Il existe une autre propriété intéressante qui est status et qui représente le code HTTP retourné par la requête. Il est bon de savoir que Firefox déclenche une erreur si on tente d'accéder à cette propriété avant que readyState ne vaille 4.
Pour voir toutes les valeurs que peut prendre status, cliquez sur le lien suivant :
Réaliser une requête et recevoir un résultat, c'est bien. Mais réaliser une requête en transmettant des données c'est mieux. Les données sont transmises de la même façon que lors de la soumission d'un formulaire, c'est-à-dire via l'une des deux méthodes GET ou POST. Évidemment, si on transmet des données, il faut que la requête porte sur un fichier capable de les interpréter correctement. Dans l'exemple suivant, nous allons envoyer deux chaînes de caractères au fichier strings2.php et celui-ci va nous les retourner « renversées ».
Comment ça marche ?
Tout commence en JS. Si la méthode sélectionnée est get, les données à transmettre sont concaténées à l'URL (cf. lignes 13-16) et si la méthode est post, elles sont envoyées via la fonction send (cf. ligne 35). Dans ce dernier cas, on doit aussi préciser l'encodage en spécifiant l'en-tête adéquat avec setRequestHeader (cf. ligne 32).
Ensuite, côté PHP, les données sont reçues, quelle que soit la méthode de transmission et les chaînes sont renversées grâce à strrev (cf. lignes 3-12). Les données reçues via la méthode POST sont décodées grâce à utf8_decode sinon les caractères accentués sont mal interprétés. La chaîne affichée par le code PHP (et retournée, donc) est de la forme Données reçues en XXX:STRING1:STRING2: où XXX vaut soit GET soit POST et où STRING1 et STRING2 sont les chaînes renversées. On précise aussi, grâce à la fonction header le type des données qui vont être transférées depuis le serveur (ici, du texte utilisant le jeu de caractères iso-8859-1) (cf. ligne 1).
Enfin, côté JS, il ne reste plus qu'à séparer les données, avec split et à mettre les chaînes dans les champs correspondants (cf. lignes 22-26).
Comme nous l'avons vu dans les exemples précédents, nous disposons d'une grande liberté d'action avec cet outil. On peut simplement afficher le résultat de la requête dans une boîte d'alerte. On peut également l'afficher dans un div (ou tout autre élément HTML). Mais on peut tout aussi bien, si la chaîne récupérée représente du code JS, exécuter ce code grâce à eval.
Voici un exemple dans lequel une liste déroulante est peuplée en fonction du choix réalisé dans une première liste. Le code JS qui permet de remplir la seconde liste est généré côté serveur, suite à une requête MySQL et simplement évalué côté client.
Comment ça marche ?
Dans cet exemple, seules les notions couvertes dans les sections 1. à 4. sont utilisées, ainsi que quelques notions élémentaires de JS et de PHP. Vous devriez donc logiquement pouvoir comprendre le code par vous-même. Si, si, j'en suis sûr.
Cette section n'est pas exhaustive. Elle présente les propriétés et méthodes les plus utiles, même s'il est vrai que cette notion est assez subjective. Pour une liste complète, je vous invite à consulter la MSDN dont un lien est donné en section 7.
D'autres pages du site :
Des exemples d'utilisation :