Tout JavaScript.com - Scripts, Tutoriaux, Forums pour webmasters et développeurs
Retour à l'accueil
Rechercher :    

Les indispensables
Magic Menu
Les meilleurs scripts
Les forums
Les tutoriaux
La référence JavaScript
Les actus du net
Les petites annonces

Shopping
Le guide complet
Hébergement web

Les javascripts
Les plus vus
Les mieux notés
La boutique

Les tutoriaux
Introduction javascript
La structure javascript
Les limites de javascript
Les popups
Les formulaires
Le DHTML
Les cookies
Les frames
Les maths
Les chaînes de caractères
Les expressions régulières
Débugger un script
AJAX / XMLHTTPRequest
Introduction au PHP
Javascript et PHP
Traiter les données PHP
Intro base de données
Optimiser ses développements
Tous les tutoriaux

Les services
Les questions fréquentes
Les forums | Le chat
L'annuaire de sites
Le livre d'or
Contacts
A propos du site
La newsletter
 Inscription à la newsletter
HTML - Texte

Les partenaires
Beauté-test
Révélateur.com
jquery













Robloche nous propose ici un tutorial passionnant sur l'utilisation des requêtes 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 dédiés au JavaScript : Peut-on réaliser une requête sur le serveur sans (re)charger une page et sans utiliser d'astuces telles qu'une frame invisible ou une fenêtre popup ? Jusqu'à peu, je pensais que la réponse était aussi claire que négative. Et puis j'ai découvert XMLHTTPRequest et la réponse est devenue : « Oui ! » Mais les documentations sur ce sujet ne se bousculent pas sur le net, notamment en français. D'où cette petite introduction aux objets XMLHTTPRequest (que nous appellerons ainsi même si le nom diffère d'un navigateur à l'autre). Pour l'instant, c'est uniquement compatible Internet Explorer et Firefox mais je crois avoir lu quelques informations intéressantes pour Opera[1]. Quant à Netscape, bah... je ne suis pas nécrophile.

Avant d'entrer dans le vif du sujet, je tiens à remercier tous les habitués du forum de ToutJavaScript.com et notamment Aurélien pour son explication limpide sur les fonctions à retardement (j'espère les avoir bien utilisées) et poof65 pour sa collaboration lors de la création d'une classe d'abstraction des objets XMLHTTPRequest.

[1] Opera est actuellement en train d'évoluer et devrait bientôt gérer complètement 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 résultat arrive deux fois. Celui de la section 4. ne fonctionne qu'avec la méthode get. Et le dernier, celui de la section 5. fait carrément planter l'application.

1. Présentation

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. Ce qui se fait de manière différente 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 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.

> Voir le code JavaScript

Comment ça marche ?

  • ligne 4 : on crée une instance de l'objet XMLHTTPRequest sous Firefox ;
  • ligne 6 : on crée une instance de l'objet XMLHTTPRequest sous IE ;
  • ligne 12 : on spécifie la méthode de transmission des données, l'URL et le mode de transmission de la requête ;
  • ligne 13 : on exécute la requête proprement dite ;
  • ligne 14 : on affiche une boîte d'alerte dès que la requête est terminée.

Note : Ces fonctions sont détaillées en section 6.

[haut de la page]

2. À quoi cela peut-il servir ?

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.responseText ou xhr_object.responseXML, selon que le résultat est au format texte (il est possible de mettre n'importe quoi dedans, tout est question d'interprétation ultérieure de ce résultat) ou XML. Remplaçons simplement l'alerte de l'exemple précédent par alert(xhr_object.responseText) (cf. ligne 14) 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.responseText. À 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.

[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 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 :

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

Comment ça marche ?

C'est le troisième argument de la fonction open (cf. ligne 12) qui spécifie que le mode doit être asynchrone.

L'objet xhr_object possède une propriété readyState (cf. ligne 15) 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 14) 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 :

> Voir toutes les valeurs

[haut de la page]

4. Transmettre des données

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 ».

Entrez deux chaînes et choisissez une méthode de transmission
Chaîne 1 : ->
Chaîne 2 : ->
Méthode : get post
> Voir le code JavaScript
> Voir le contenu de strings2.php

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 21-24) et si la méthode est post, elles sont envoyées via la fonction send (cf. ligne 42). Dans ce dernier cas, on doit aussi préciser l'encodage en spécifiant l'en-tête adéquat avec setRequestHeader (cf. ligne 40).

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: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 30-34).

[haut de la page]

5. Exemple concret d'utilisation

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.

Faites un choix dans la liste de gauche
et observez le résultat dans celle de droite
Famille :    Espèces :
> 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 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.

[haut de la page]

6. Propriétés et méthodes

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.

Propriétés

  • onreadystatechange : Spécifie la fonction à appeler lorsque la propriété readyState varie. lecture/écriture. (Cf. section 3 pour les valeurs)
  • readyState : Représente l'état d'avancement de la requête. lecture seule.
  • responseText : Chaîne de caractères contenant la réponse à la requête. lecture seule.
  • responseXML : Objet XML contenant la réponse à la requête. lecture seule.
  • status : Représente le code HTTP retourné par la requête. lecture seule. (Cf. section 3 pour les valeurs)

Méthodes

  • abort() : Annule la requête courante.
  • getAllResponseHeaders() : Retourne les noms et les valeurs de tous les en-têtes HTTP sous forme d'une chaîne.
  • getResponseHeader(headerName) : Récupère la valeur d'un certain en-tête HTTP (headerName) sous forme d'une chaîne.
  • open(method, url[, asynchrone[, user[, password]]]) : Initialise une requête en spécifiant la méthode (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 requête HTTP au serveur en transmettant éventuellement des données (data doit alors être différent de null) sous forme d'une « postable string » (je suis preneur pour une traduction) ou sous forme d'un objet DOM.
  • setTimeouts(timeout) : Spécifie la durée maximale (timeout) accordée à une requête pour quelle s'effectue complètement.
  • setRequestHeader(headerName, headerValue) : Spécifie un en-tête HTTP (headerName et headerValue) à envoyer avec la requête.

[haut de la page]

7. Quelques liens

Des exemples d'utilisation :

  • Une petite page de démonstration (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 même). 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 réaliser certaines opérations complexes en ne fournissant que quelques paramètres :
    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 sûr, 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 régulièrement fleurir de nouvelles utilisations de ces requêtes JS sur le net. Et ça ne risque pas de s'arrêter, tant il est vrai que ça simplifie la vie des visiteurs. Observez bien les sites que vous fréquentez et essayez de deviner s'ils utilisent cette technique.

D'autres liens utiles :

[haut de la page]



Merci et bravo à robloche pour son tutorial très intéressant et très clair sur cette nouvelle façon de voir le développement côté client !
Pour discuter de cet article, rendez-vous sur cette discussion du forum




| © Tout JavaScript.com 1999-2005 | Scripts | Tutoriaux | Forums | Référence | Magic Menu V2 | Mailociraptor | Petites annonces informatiques |


Edité par DevTribu sarl  Google
Serveur dédié vps : Page générée en 6 msec
23/08/2014 09:27:48 - OB = off