Retourner à la page d'accueil de TJS
Robloche nous propose ici un tutorial passionnant sur l'utilisation des requtes serveur en JavaScript.
Merci lui pour son travail et pour l'autorisation de reproduction sur les pages du site.

Une question revient souvent sur les forums ddis au JavaScript : Peut-on raliser une requte sur le serveur sans (re)charger une page et sans utiliser d'astuces telles qu'une frame invisible ou une fentre popup ? Jusqu' peu, je pensais que la rponse tait aussi claire que ngative. Et puis j'ai dcouvert XMLHTTPRequest et la rponse est devenue : « Oui ! » Mais les documentations sur ce sujet ne se bousculent pas sur le net, notamment en franais. D'o cette petite introduction aux objets XMLHTTPRequest (que nous appellerons ainsi mme si le nom diffre d'un navigateur l'autre). Pour l'instant, c'est uniquement compatible Internet Explorer et Firefox mais je crois avoir lu quelques informations intressantes pour Opera[1]. Quant Netscape, bah... je ne suis pas ncrophile.

Avant d'entrer dans le vif du sujet, je tiens remercier tous les habitus du forum de ToutJavaScript.com et notamment Aurlien pour son explication limpide sur les fonctions retardement (j'espre les avoir bien utilises) et poof65 pour sa collaboration lors de la cration d'une classe d'abstraction des objets XMLHTTPRequest.

[1] Opera est actuellement en train d'voluer et devrait bientt grer compltement ces objets. Au moment o j'cris ces lignes, les exemples des sections 1. et 2. fonctionnent normalement sous Opera 8 beta. L'exemple de la section 3. fonctionne mais le rsultat arrive deux fois. Celui de la section 4. ne fonctionne qu'avec la mthode get. Et le dernier, celui de la section 5. fait carrment planter l'application.

1. Prsentation

Comme leur nom ne l'indique pas, les objets XMLHTTPRequest permettent de rcuprer toutes sortes de donnes, et pas seulement des fichiers XML. Pour effectuer une requte, il faut tout d'abord dclarer une certaine variable. Ce qui se fait de manire diffrente avec IE et Firefox. Sous IE, on utilise un objet ActiveX et sous Firefox, on dispose d'un type ad hoc. Ensuite, on envoie la requte et enfin, on attend la rponse. Ci-aprs, vous pouvez voir un exemple trs basique faisant une requte sur la prsente page (location.href). Une fois la rponse obtenue, une bote d'alerte s'affiche.

> Voir le code JavaScript

Comment a marche ?

  • ligne 4 : on cre une instance de l'objet XMLHTTPRequest sous Firefox ;
  • ligne 6 : on cre une instance de l'objet XMLHTTPRequest sous IE ;
  • ligne 12 : on spcifie la mthode de transmission des donnes, l'URL et le mode de transmission de la requte ;
  • ligne 13 : on excute la requte proprement dite ;
  • ligne 14 : on affiche une bote d'alerte ds que la requte est termine.

Note : Ces fonctions sont dtailles en section 6.

[haut de la page]

2. quoi cela peut-il servir ?

Dans l'exemple prcdent, la requte se contente de demander un certain fichier sans s'occuper du rsultat. Mais en fait, lorsque la requte se termine, on reoit (et heureusement) des informations du serveur. Ces informations sont contenues dans la variable xhr_object.responseText ou xhr_object.responseXML, selon que le rsultat est au format texte (il est possible de mettre n'importe quoi dedans, tout est question d'interprtation ultrieure de ce rsultat) ou XML. Remplaons simplement l'alerte de l'exemple prcdent par alert(xhr_object.responseText) (cf. ligne 14) et voyons le rsultat :

Comme vous l'avez constat, c'est tout le code de la prsente page HTML qui s'est affich (a a d'ailleurs d sortir de l'cran, dsol). En fait, lors d'une telle requte, 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 excut et c'est le rsultat de son excution qui se retrouvera dans xhr_object.responseText. partir de l, on se rend vite compte qu'il n'y a pas de limite l'utilisation de ce type de requte. On peut simplement afficher le rsultat reu avec un alert. On peut mettre le rsultat dans un DIV (ou tout autre conteneur HTML), mais on peut tout aussi bien rcuprer et excuter du code JS grce eval.

Note : La section 5 prsente un exemple concret d'utilisation.

[haut de la page]

3. Synchrone Vs. Asynchrone

Dans les exemples que nous avons vus jusqu' maintenant, c'est le mode synchrone qui tait utilis. Cela signifie que tant que le rsultat de la requte ne nous est pas parvenu, le script est en pause et le navigateur bloqu. Avec un bon dbit et/ou peu de donnes transmettre, on pourrait s'en contenter mais cela peut vite s'avrer gnant pour l'utilisateur qui voit son navigateur fig. Ce mode de transmission est donc proscrire. Heureusement, il existe le mode asynchrone. Dans ce mode, aprs avoir envoy la requte via send, le script poursuit son excution, sans bloquer le navigateur. videmment, dans ce mode, il faut prvoir quelque chose pour nous prvenir quand la requte a abouti. C'est le rle de la fonction onreadystatechange (en fait, onreadystatechange est une proprit 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 requte sur un simple fichier texte :

> Voir le code JavaScript
> Voir le contenu de foo.txt

Comment a marche ?

C'est le troisime argument de la fonction open (cf. ligne 12) qui spcifie que le mode doit tre asynchrone.

L'objet xhr_object possde une proprit readyState (cf. ligne 15) qui prend successivement 5 valeurs rcapitules dans le tableau suivant :

Et lors de chaque changement d'tat de readyState, la fonction onreadystatechange (cf. ligne 14) est appele. On peut ainsi lui faire faire ce que l'on veut en fonction de l'avancement de la requte. Mais de toute manire, c'est l'tat 4 qui nous intresse et il est gnralement trs rapidement atteint. Il existe une autre proprit intressante qui est status et qui reprsente le code HTTP retourn par la requte. Il est bon de savoir que Firefox dclenche une erreur si on tente d'accder cette proprit avant que readyState ne vaille 4. Pour voir toutes les valeurs que peut prendre status, cliquez sur le lien suivant :

> Voir toutes les valeurs

[haut de la page]

4. Transmettre des donnes

Raliser une requte et recevoir un rsultat, c'est bien. Mais raliser une requte en transmettant des donnes c'est mieux. Les donnes sont transmises de la mme faon que lors de la soumission d'un formulaire, c'est--dire via l'une des deux mthodes get ou post. videmment, si on transmet des donnes, il faut que la requte porte sur un fichier capable de les interprter correctement. Dans l'exemple suivant, nous allons envoyer deux chanes de caractres au fichier strings2.php et celui-ci va nous les retourner « renverses ».

Entrez deux chanes et choisissez une mthode de transmission
Chane 1 : ->
Chane 2 : ->
Mthode : get post
> Voir le code JavaScript
> Voir le contenu de strings2.php

Comment a marche ?

Tout commence en JS. Si la mthode slectionne est get, les donnes transmettre sont concatnes l'URL (cf. lignes 21-24) et si la mthode est post, elles sont envoyes via la fonction send (cf. ligne 42). Dans ce dernier cas, on doit aussi prciser l'encodage en spcifiant l'en-tte adquat avec setRequestHeader (cf. ligne 40).

Ensuite, ct PHP, les donnes sont reues, quelle que soit la mthode de transmission et les chanes sont renverses grce strrev (cf. lignes 3-12). Les donnes reues via la mthode POST sont dcodes grce utf8_decode sinon les caractres accentus sont mal interprts. La chane affiche par le code PHP (et retourne, donc) est de la forme Donnes reues en XXX:STRING1:STRING2: o XXX vaut soit GET soit POST et o STRING1 et STRING2 sont les chanes renverses. On prcise aussi, grce la fonction header le type des donnes qui vont tre transfres depuis le serveur (ici, du texte utilisant le jeu de caractres iso-8859-1) (cf. ligne 1).

Enfin, ct JS, il ne reste plus qu' sparer les donnes, avec split et mettre les chanes dans les champs correspondants (cf. lignes 30-34).

[haut de la page]

5. Exemple concret d'utilisation

Comme nous l'avons vu dans les exemples prcdents, nous disposons d'une grande libert d'action avec cet outil. On peut simplement afficher le rsultat de la requte dans une bote d'alerte. On peut galement l'afficher dans un div (ou tout autre lment HTML). Mais on peut tout aussi bien, si la chane rcupre reprsente du code JS, excuter ce code grce eval.

Voici un exemple dans lequel une liste droulante est peuple en fonction du choix ralis dans une premire liste. Le code JS qui permet de remplir la seconde liste est gnr ct serveur, suite une requte MySQL et simplement valu ct client.

Faites un choix dans la liste de gauche
et observez le rsultat dans celle de droite
Famille :    Espces :
> Voir le code JavaScript
> Voir le contenu de species.php
> Voir la table « Animals »

Comment a marche ?

Dans cet exemple, seules les notions couvertes dans les sections 1. 4. sont utilises, ainsi que quelques notions lmentaires de JS et de PHP. Vous devriez donc logiquement pouvoir comprendre le code par vous-mme. Si, si, j'en suis sr.

[haut de la page]

6. Proprits et mthodes

Cette section n'est pas exhaustive. Elle prsente les proprits et mthodes les plus utiles, mme s'il est vrai que cette notion est assez subjective. Pour une liste complte, je vous invite consulter la MSDN dont un lien est donn en section 7.

Proprits

  • onreadystatechange : Spcifie la fonction appeler lorsque la proprit readyState varie. lecture/criture. (Cf. section 3 pour les valeurs)
  • readyState : Reprsente l'tat d'avancement de la requte. lecture seule.
  • responseText : Chane de caractres contenant la rponse la requte. lecture seule.
  • responseXML : Objet XML contenant la rponse la requte. lecture seule.
  • status : Reprsente le code HTTP retourn par la requte. lecture seule. (Cf. section 3 pour les valeurs)

Mthodes

  • abort() : Annule la requte courante.
  • getAllResponseHeaders() : Retourne les noms et les valeurs de tous les en-ttes HTTP sous forme d'une chane.
  • getResponseHeader(headerName) : Rcupre la valeur d'un certain en-tte HTTP (headerName) sous forme d'une chane.
  • open(method, url[, asynchrone[, user[, password]]]) : Initialise une requte en spcifiant la mthode (method), l'URL (url), si le mode est asynchrone (asyncFlag vaut true ou false) et en indiquant d'ventuelles informations d'identification (user et password).
  • send(data) : Envoie la requte HTTP au serveur en transmettant ventuellement des donnes (data doit alors tre diffrent de null) sous forme d'une « postable string » (je suis preneur pour une traduction) ou sous forme d'un objet DOM.
  • setTimeouts(timeout) : Spcifie la dure maximale (timeout) accorde une requte pour quelle s'effectue compltement.
  • setRequestHeader(headerName, headerValue) : Spcifie un en-tte HTTP (headerName et headerValue) envoyer avec la requte.

[haut de la page]

7. Quelques liens

Des exemples d'utilisation :

  • Une petite page de dmonstration (qui perd un peu de son sens face ce tutorial) :
    http://robloche.free.fr/javascript/js_request/test.html
  • Et voici le concept pouss un plus loin, avec un jeu de morpion acceptant un grand nombre de participants (enfin, deux par jeu, quand mme). J'ai crit dans ce but une classe d'abstraction qui permet de manipuler ces objets sans se soucier du navigateur. Cette classe constitue une surcouche aux objets XMLHTTPRequest et permet de raliser certaines oprations complexes en ne fournissant que quelques paramtres :
    http://robloche.free.fr/javascript/morpion/morpion.php
  • Une nouvelle mouture de Google, actuellement en version beta, propose des suggestions pour votre recherche, en utilisant cette technique :
    http://www.google.com/webhp?complete=1&hl=en
  • Et bien sr, tout ceux qui ont un compte Gmail savent quel point il est fait un usage intensif de cette technologie :
    http://gmail.google.com
  • Depuis quelques mois, on voit rgulirement fleurir de nouvelles utilisations de ces requtes JS sur le net. Et a ne risque pas de s'arrter, tant il est vrai que a simplifie la vie des visiteurs. Observez bien les sites que vous frquentez et essayez de deviner s'ils utilisent cette technique.

D'autres liens utiles :

[haut de la page]



Merci et bravo robloche pour son tutorial trs intressant et trs clair sur cette nouvelle faon de voir le dveloppement ct client !
Pour discuter de cet article, rendez-vous sur cette discussion du forum



Chercher une référence

Le graph des objets Javascript



Chargement
en cours...

Le guide complet du javascript

Le Guide Complet du JavascriptEn savoir plus sur mon livre aux Editions Micro Application