La plupart des applications Web utilisent un modèle requête/réponse pour obtenir une page HTML complète à partir du serveur. Il s'agit souvent d'un processus répétitif consistant à cliquer sur un bouton, à attendre que le serveur réponde, à cliquer sur un autre bouton, puis à attendre à nouveau. Avec Ajax et l'objet XMLHttpRequest, vous pouvez utiliser un modèle de requête/réponse qui n'oblige pas l'utilisateur à attendre une réponse du serveur. Dans cet article, Brett McLaughlin explique comment créer des instances XMLHttpRequest capables de s'adapter à différents navigateurs, d'établir et d'envoyer des requêtes et de répondre au serveur.
Dans l'article précédent de cette série (voir Ressources pour un lien), nous avons présenté les applications Ajax et examiné les concepts de base qui pilotent les applications Ajax. Au cœur de tout cela se trouvent de nombreuses technologies que vous connaissez probablement déjà : JavaScript, HTML et XHTML, un peu de HTML dynamique et le DOM (Document Object Model). Cet article zoomera sur un point et se concentrera sur des détails spécifiques à Ajax.
Dans cet article, vous commencerez à entrer en contact avec les objets et méthodes de programmation les plus basiques et fondamentaux liés à Ajax : l'objet XMLHttpRequest. Cet objet n'est en réalité qu'un fil conducteur qui couvre toutes les applications Ajax et, comme vous pouvez vous y attendre, vous devez bien comprendre cet objet pour réaliser tout votre potentiel de programmation. En fait, vous constaterez parfois que pour utiliser correctement XMLHttpRequest, vous ne pouvez évidemment pas utiliser XMLHttpRequest. Que se passe-t-il?
Le Web 2.0 en un coup d'œil
Avant d'entrer dans le code, examinons les perspectives récentes : il est important d'être très clair sur le concept du Web 2.0. Lorsque vous entendez le terme Web 2.0, vous devez d'abord vous demander « Qu'est-ce que le Web 1.0 ? » Bien qu'il soit rare d'entendre les gens mentionner le Web 1.0, il fait en fait référence au Web traditionnel avec un modèle de demande et de réponse complètement différent. Par exemple, accédez au site Web Amazon.com et cliquez sur un bouton ou saisissez un terme de recherche. Une requête est envoyée au serveur et la réponse est renvoyée au navigateur. La requête n'est pas simplement une liste de livres et de titres, mais une autre page HTML complète. Par conséquent, vous pouvez constater un scintillement ou une instabilité lorsque le navigateur Web redessine la page avec le nouveau code HTML. En fait, les demandes et les réponses sont clairement visibles à chaque nouvelle page que vous voyez.
Le Web 2.0 élimine (en grande partie) cette interaction visible de va-et-vient. Par exemple, visitez un site comme Google Maps ou Flickr (voir Ressources pour les liens vers ces sites Web 2.0 et compatibles Ajax). Sur Google Maps, par exemple, vous pouvez faire glisser la carte pour effectuer un zoom avant et arrière avec un redessin minimal. Bien sûr, il y a encore des demandes et des réponses, mais elles sont cachées dans les coulisses. En tant qu'utilisateur, l'expérience est plus confortable et ressemble beaucoup à une application de bureau. Ce nouveau sentiment et ce nouveau paradigme sont ce que vous obtenez lorsque quelqu'un mentionne le Web 2.0.
Le souci est de rendre possibles ces nouvelles interactions. Évidemment, vous devez toujours faire des requêtes et recevoir des réponses, mais c'est la refonte HTML pour chaque interaction requête/réponse qui crée le sentiment d'interactions Web lentes et maladroites. Il est donc clair que nous avons besoin d'un moyen d'envoyer des requêtes et de recevoir des réponses contenant uniquement les données requises plutôt que la page HTML entière. La seule fois où vous avez besoin d’obtenir l’intégralité de la nouvelle page HTML, c’est lorsque vous souhaitez que l’utilisateur voie la nouvelle page.
Mais la plupart des interactions ajoutent des détails aux pages existantes, modifient le texte principal ou écrasent les données originales. Dans ces cas, les méthodes Ajax et Web 2.0 permettent d'envoyer et de recevoir des données sans mettre à jour l'intégralité de la page HTML. Pour ceux qui passent beaucoup de temps en ligne, cette fonctionnalité peut rendre vos applications plus rapides et plus réactives, les incitant à revenir sur votre site de temps en temps.
Introduction à XMLHttpRequest
Pour véritablement réaliser ce magnifique miracle, vous devez être très familier avec un objet JavaScript, à savoir XMLHttpRequest. Ce petit objet existe en fait dans plusieurs navigateurs depuis un certain temps et est au cœur du Web 2.0, d'Ajax et de la plupart des autres éléments que j'aborderai dans cette chronique au cours des prochains mois. Pour vous donner un aperçu rapide, voici quelques-unes des méthodes et propriétés qui seront utilisées sur cet objet.
·open() : Établit une nouvelle requête au serveur.
·send() : Envoie une requête au serveur.
·abort() : abandonne la requête en cours.
·readyState : fournit l'état prêt du code HTML actuel.
·responseText : le texte de réponse à la demande renvoyé par le serveur.
Ne vous inquiétez pas si vous ne les connaissez pas (ou l'un d'entre eux), nous aborderons chaque méthode et propriété dans les prochains articles. Ce que vous devez savoir maintenant, c'est exactement quoi faire avec XMLHttpRequest. Notez que ces méthodes et propriétés sont liées à l’envoi de requêtes et au traitement des réponses. En fait, si vous examinez toutes les méthodes et propriétés de XMLHttpRequest, vous constaterez qu'elles se rapportent toutes à un modèle requête/réponse très simple. Évidemment, nous n'allons pas rencontrer un objet GUI particulièrement nouveau ou une manière super mystérieuse de créer une interaction utilisateur, nous allons utiliser des requêtes et des réponses très simples. Cela peut paraître peu, mais bien utiliser cet objet peut révolutionner votre application.
Simple new
nécessite d’abord de créer une nouvelle variable et de lui attribuer une instance d’objet XMLHttpRequest. C'est aussi simple que d'utiliser le mot-clé new sur le nom de l'objet en JavaScript, comme indiqué dans le listing 1.
Listing 1. Création d'un nouvel objet XMLHttpRequest
<script language="javascript" type="text/javascript">
var request = new XMLHttpRequest();
</script>
N'est-ce pas difficile ? N'oubliez pas que JavaScript ne nécessite pas que vous spécifiiez des types de variables, vous n'avez donc pas besoin de faire ce que vous faites dans le listing 2 (ce que vous pourriez faire dans le langage Java).
Listing 2. Pseudocode Java pour créer une requête XMLHttpRequestXMLHttpRequest
= new XMLHttpRequest();
Ainsi, en JavaScript, vous créez une variable en utilisant var, vous lui donnez un nom (tel que "request"), puis vous lui attribuez une nouvelle instance XMLHttpRequest. L'objet peut ensuite être utilisé dans des fonctions.
Gestion des erreurs
Toutes sortes de choses peuvent se passer mal, et le code ci-dessus ne fournit aucune gestion des erreurs. Une meilleure approche consiste à créer l'objet et à le quitter en douceur si quelque chose ne va pas. Par exemple, tous les navigateurs plus anciens (croyez-le ou non, il y a encore des gens qui utilisent des versions plus anciennes de Netscape Navigator) ne prennent pas en charge XMLHttpRequest, et vous devez informer ces utilisateurs que quelque chose ne va pas. Le listing 3 montre comment créer cet objet pour émettre un avertissement JavaScript lorsqu'un problème survient.
Listing 3. Création d'un XMLHttpRequest avec des capacités de gestion des erreurs
<langage de script="javascript" type="text/javascript">
var requête = faux ;
essayer {
requête = nouveau XMLHttpRequest();
} catch (échec) {
demande = faux ;
}
si (!request)
alert("Erreur lors de l'initialisation de XMLHttpRequest !");
</script>
Assurez-vous de comprendre ces étapes :
1. Créez une nouvelle requête de variable et attribuez-lui la valeur false. False sera utilisé plus tard comme condition de jugement, ce qui signifie que l'objet XMLHttpRequest n'a pas encore été créé.
2. Ajoutez un bloc try/catch :
1) Essayez de créer un objet XMLHttpRequest.
2) En cas d'échec (catch (failed)), il est garanti que la valeur de la requête est toujours fausse.
3. Vérifiez si la requête est toujours fausse (elle ne le sera pas si tout est normal).
4. Si un problème survient (la demande est fausse), utilisez l'avertissement JavaScript pour informer l'utilisateur qu'un problème est survenu.
Le code est très simple et pour la plupart des développeurs JavaScript et Web, il faudra plus de temps pour vraiment le comprendre que pour lire et écrire le code. Vous disposez désormais d'un morceau de code de création d'objet XMLHttpRequest dont les erreurs sont vérifiées et qui peut vous indiquer ce qui n'a pas fonctionné.
Tout semble bien se passeravec Microsoft
, du moins jusqu'à ce que vous essayiez le code avec Internet Explorer. Si vous expérimentez ainsi, vous verrez la mauvaise situation illustrée à la figure 1.
Figure 1. Erreur de rapport d'Internet Explorer
Quelque chose ne va clairement pas, et Internet Explorer n’est pas un navigateur obsolète puisqu’il est utilisé par 70 % du monde. En d’autres termes, si vous ne supportez pas Microsoft et Internet Explorer, vous ne serez pas populaire dans le monde du Web ! Nous devons donc adopter une approche différente avec les navigateurs Microsoft.
Il a été vérifié que Microsoft prend en charge Ajax, mais sa version XMLHttpRequest porte un nom différent. En fait, il l'appelle plusieurs choses différentes. Si vous utilisez des versions plus récentes d'Internet Explorer, vous devez utiliser l'objet Msxml2.XMLHTTP, tandis que les anciennes versions d'Internet Explorer utilisent Microsoft.XMLHTTP. Nous devons prendre en charge les deux types d'objets (ainsi que les navigateurs non Microsoft). Jetez un œil au listing 4, qui s'appuie sur le code précédent et ajoute la prise en charge de Microsoft.
Microsoft est-il impliqué ?
De nombreux écrits ont été publiés sur l'intérêt et l'implication croissants d'Ajax et de Microsoft dans ce domaine. En fait, il est dit que la dernière version d'Internet Explorer de Microsoft - la version 7.0, prévue pour le second semestre 2006 - commencera à prendre en charge directement XMLHttpRequest, vous permettant d'utiliser le nouveau mot-clé au lieu de tout le code de création Msxml2.XMLHTTP. Mais ne soyez pas trop excité, les anciens navigateurs doivent toujours être pris en charge, donc le code multi-navigateurs ne va pas disparaître de si tôt.
Listing 4. Ajout de la prise en charge des navigateurs Microsoft
<langage de script="javascript" type="text/javascript">
var requête = faux ;
essayer {
requête = nouveau XMLHttpRequest();
} attraper (essayerMicrosoft) {
essayer {
request = new ActiveXObject("Msxml2.XMLHTTP");
} catch (autremicrosoft) {
essayer {
request = new ActiveXObject("Microsoft.XMLHTTP");
} catch (échec) {
demande = faux ;
}
}
}
si (!request)
alert("Erreur lors de l'initialisation de XMLHttpRequest !");
</script>
Il est facile d'être dérouté par ces accolades, c'est pourquoi chaque étape est présentée ci-dessous :
1. Créez une nouvelle requête de variable et attribuez-lui la valeur false. Utilisez false comme condition de jugement, ce qui signifie que l'objet XMLHttpRequest n'a pas encore été créé.
2. Ajoutez un bloc try/catch :
1) Essayez de créer un objet XMLHttpRequest.
2) En cas d'échec (catch (trymicrosoft)) :
1>Essayez d'utiliser une version plus récente du navigateur Microsoft pour créer un objet compatible Microsoft (Msxml2.XMLHTTP).
2> En cas d'échec (catch (othermicrosoft)), essayez de créer un objet compatible Microsoft (Microsoft.XMLHTTP) à l'aide d'une ancienne version du navigateur Microsoft.
2) En cas d'échec (catch (failed)), il est garanti que la valeur de la requête est toujours fausse.
3. Vérifiez si la requête est toujours fausse (elle ne le sera pas si tout se passe bien).
4. Si un problème survient (la demande est fausse), utilisez l'avertissement JavaScript pour informer l'utilisateur qu'un problème est survenu.
Après avoir ainsi modifié le code et l'avoir testé avec Internet Explorer, vous devriez voir le formulaire créé (sans message d'erreur). Les résultats de mon expérience sont présentés dans la figure 2.
Figure 2. Internet Explorer fonctionne normalement
Statique ou dynamique
Jetez un autre coup d'œil aux listings 1, 3 et 4. Notez que tout ce code est imbriqué directement dans la balise script. Un code JavaScript comme celui-ci qui n'est pas placé dans un corps de méthode ou de fonction est appelé JavaScript statique. Cela signifie que le code est exécuté à un moment donné avant que la page ne soit affichée à l'utilisateur. (Bien que la spécification ne sache pas avec une précision totale quel effet ce code aura sur le navigateur lors de son exécution, il est garanti qu'il sera exécuté avant que l'utilisateur puisse interagir avec la page.) C'est également la méthode générale la plus utilisée. Les programmeurs Ajax créent des objets XMLHttpRequest.
Cela dit, vous pouvez également mettre ce code dans une méthode comme le Listing 5.
Listing 5. Déplacement du code de création XMLHttpRequest dans une méthode
<script langage="javascript" type="text/javascript">
var requête ;
fonction createRequest() {
essayer {
requête = nouveau XMLHttpRequest();
} attraper (essayerMicrosoft) {
essayer {
request = new ActiveXObject("Msxml2.XMLHTTP");
} catch (autremicrosoft) {
essayer {
request = new ActiveXObject("Microsoft.XMLHTTP");
} catch (échec) {
demande = faux ;
}
}
}
si (!request)
alert("Erreur lors de l'initialisation de XMLHttpRequest !");
}
</script>
Si vous écrivez votre code de cette façon, vous devez appeler cette méthode avant de gérer Ajax. Un code comme le listing 6 est donc également nécessaire.
Listing 6. Créer une méthode à l'aide de XMLHttpRequest
<script langage="javascript" type="text/javascript">
var requête ;
fonction createRequest() {
essayer {
requête = nouveau XMLHttpRequest();
} attraper (essayerMicrosoft) {
essayer {
request = new ActiveXObject("Msxml2.XMLHTTP");
} catch (autremicrosoft) {
essayer {
request = new ActiveXObject("Microsoft.XMLHTTP");
} catch (échec) {
demande = faux ;
}
}
}
si (!request)
alert("Erreur lors de l'initialisation de XMLHttpRequest !");
}
fonction getCustomerInfo() {
createRequest();
// Faire quelque chose avec la variable de requête
}
</script>
Le seul problème avec ce code est qu'il retarde la notification des erreurs, c'est pourquoi la plupart des programmeurs Ajax n'utilisent pas cette approche. Supposons que vous ayez un formulaire complexe avec 10 ou 15 champs, cases de sélection, etc., et que vous souhaitiez activer du code Ajax lorsque l'utilisateur saisit du texte dans le 14ème champ (de haut en bas dans l'ordre du formulaire). À ce stade, l'exécution de getCustomerInfo() tente de créer un objet XMLHttpRequest, mais (dans ce cas) échoue. L’utilisateur reçoit alors un avertissement lui indiquant clairement qu’il ne peut pas utiliser l’application. Mais les utilisateurs passent déjà beaucoup de temps à saisir des données dans les formulaires ! C’est très ennuyeux, et être ennuyeux n’incitera évidemment pas les utilisateurs à revenir sur votre site.
Si vous utilisez du JavaScript statique, les utilisateurs verront très rapidement des messages d'erreur lorsqu'ils cliqueront sur la page. C'est aussi ennuyeux, n'est-ce pas ? L'utilisateur peut croire à tort que votre application Web ne peut pas fonctionner sur son navigateur. Mais c'est certainement mieux que de passer 10 minutes à saisir des informations pour ensuite voir la même erreur s'afficher. Par conséquent, je recommande d’écrire du code statique pour permettre aux utilisateurs de détecter les problèmes le plus tôt possible.
Aprèsavoir envoyé une requête avec XMLHttpRequest
et obtenu l'objet de requête, vous pouvez entrer dans le cycle requête/réponse. N'oubliez pas que le seul objectif de XMLHttpRequest est de vous permettre d'envoyer des requêtes et de recevoir des réponses. Tout le reste relève du travail de JavaScript, CSS ou autre code de la page : modifier l'interface utilisateur, changer d'image, interpréter les données renvoyées par le serveur. Après avoir préparé le XMLHttpRequest, vous pouvez envoyer la requête au serveur.
Bienvenue dans Sandbox
Ajax utilise un modèle de sécurité sandbox. Par conséquent, le code Ajax (en particulier l'objet XMLHttpRequest) ne peut envoyer des requêtes qu'au même domaine dans lequel il se trouve. Nous aborderons davantage la sécurité et Ajax dans un prochain article, mais pour l'instant, sachez que le code exécuté sur la machine locale ne peut envoyer des requêtes qu'aux scripts côté serveur sur la machine locale. Si vous souhaitez que le code Ajax s'exécute sur www.breakneckpizza.com , la requête doit être envoyée à partir d'un script exécuté sur www.breakneck.com .
Pour définir l'URL du serveur,
vous devez d'abord déterminer l'URL du serveur connecté. Ce n'est pas une exigence particulière pour Ajax, mais il faut quand même établir la connexion, et maintenant il faut évidemment savoir comment construire une URL. Dans la plupart des applications, cette URL est construite à partir d’une combinaison de données statiques et de données provenant d’un formulaire traité par l’utilisateur. Par exemple, le code JavaScript du listing 7 récupère la valeur du champ du numéro de téléphone et l'utilise pour construire une URL.
Listing 7. Création de l'URL de la requête
<langage de script="javascript" type="text/javascript">
var requête = faux ;
essayer {
requête = nouveau XMLHttpRequest();
} attraper (essayerMicrosoft) {
essayer {
request = new ActiveXObject("Msxml2.XMLHTTP");
} catch (autremicrosoft) {
essayer {
request = new ActiveXObject("Microsoft.XMLHTTP");
} catch (échec) {
demande = faux ;
}
}
}
si (!request)
alert("Erreur lors de l'initialisation de XMLHttpRequest !");
function getCustomerInfo() {
var téléphone = document.getElementById("téléphone").value;
var url = "/cgi-local/lookupCustomer.php?phone=" + escape(phone);
}
</script>
Rien de difficile à comprendre ici. Tout d'abord, le code crée une nouvelle variable phone et lui attribue la valeur du champ du formulaire avec l'ID "phone". Le listing 8 montre le XHTML de ce formulaire, où vous pouvez voir le champ phone et son attribut id.
Listing 8. Forme Break Neck Pizza
<corps>
<p><img src="breakneck-logo_4c.gif" alt="Pizza au cou cassé" /></p>
<formulaire d'action="POST">
<p>Entrez votre numéro de téléphone :
<input type="text" size="14" name="phone" id="phone"
onChange="getCustomerInfo();" />
</p>
<p>Votre commande sera livrée</p>
<div id="adresse"></div>
<p>Tapez votre commande ici :</p>
<p><textarea name="order" rows="6" cols="50" id="order"></textarea></p>
<p><input type="submit" value="Commander une pizza" id="submit" /></p>
</form>
</body>
Notez également que lorsque l'utilisateur entre un numéro de téléphone ou modifie le numéro de téléphone, la méthode getCustomerInfo() présentée dans le listing 8 est déclenchée. Cette méthode obtient le numéro de téléphone et construit une chaîne URL stockée dans la variable url. N'oubliez pas que, comme le code Ajax est en bac à sable et ne peut se connecter qu'au même domaine, il n'est en fait pas nécessaire d'indiquer un nom de domaine dans l'URL. Le script dans cet exemple s'appelle /cgi-local/lookupCustomer.php. Enfin, le numéro de téléphone est ajouté au script en tant que paramètre GET : "phone=" + escape(phone).
Si vous n'avez jamais vu la méthode escape() auparavant, elle est utilisée pour échapper tous les caractères qui ne peuvent pas être envoyés correctement en texte clair. Par exemple, les espaces dans les numéros de téléphone seront convertis en caractères %20, permettant à ces caractères d'être transmis dans l'URL.
Vous pouvez ajouter autant de paramètres que nécessaire. Par exemple, si vous devez ajouter un autre paramètre, ajoutez-le simplement à l'URL et séparez-le par le caractère esperluette (&) [le premier paramètre est séparé du nom du script par un point d'interrogation (?)].
Ouvrir la requête
Une fois que vous avez l'URL à laquelle vous connecter, vous pouvez configurer la requête. Cela peut être accompli en utilisant la méthode open() de l'objet XMLHttpRequest. Cette méthode comporte cinq paramètres :
request-type : le type de requête à envoyer. Les valeurs typiques sont GET ou POST, mais une requête HEAD peut également être envoyée.
url : l'URL à laquelle se connecter.
asynch : true si vous souhaitez utiliser une connexion asynchrone, false sinon. Ce paramètre est facultatif et sa valeur par défaut est true.
nom d'utilisateur : si une authentification est requise, vous pouvez spécifier le nom d'utilisateur ici. Ce paramètre facultatif n'a pas de valeur par défaut. mot de passe : si une authentification est requise, vous pouvez spécifier un mot de passe ici. Ce paramètre facultatif n'a pas de valeur par défaut.
Est-ce que open() s'ouvre ?
Les développeurs Internet ne sont pas d'accord sur ce que fait exactement la méthode open(). Mais cela n’ouvre pas réellement une demande. Si vous surveillez le réseau et le transfert de données entre une page XHTML/Ajax et son script de connexion, vous ne verrez aucune communication lorsque la méthode open() est appelée. On ne sait pas pourquoi ce nom a été choisi, mais ce n'est clairement pas un bon choix.
Habituellement, les trois premiers paramètres sont utilisés. En fait, même si une connexion asynchrone est requise, le troisième paramètre doit être spécifié comme « true ». Il s'agit de la valeur par défaut, mais insister pour spécifier explicitement si la requête est asynchrone ou synchrone est plus facile à comprendre.
Les combiner ensemble donne généralement une ligne de code comme celle présentée dans le listing 9.
Listing 9.
Fonction de requête ouverte getCustomerInfo() {
var téléphone = document.getElementById("téléphone").value;
var url = "/cgi-local/lookupCustomer.php?phone=" + escape(phone);
request.open("GET", url, true);
}
Une fois l'URL configurée, le reste est simple. Pour la plupart des requêtes, GET suffit (vous verrez quand POST est requis dans un article ultérieur), plus l'URL, et c'est tout ce dont vous avez besoin pour utiliser la méthode open().
Défier l'asynchronicité
Dans le prochain article de cette série, je passerai beaucoup de temps à écrire et à utiliser du code asynchrone, mais vous devez comprendre pourquoi le dernier paramètre de open() est si important. Dans un modèle de requête/réponse général, tel que le Web 1.0, le client (un navigateur ou un code exécuté sur la machine locale) envoie une requête au serveur. La requête est synchrone, c'est-à-dire que le client attend une réponse du serveur. Lorsque le client attend, vous serez informé de l'attente sous au moins une forme :
· Sablier (surtout sous Windows).
· Balle qui tourne (généralement sur les machines Mac).
·L'application se fige et après un certain temps, le curseur change.
C'est exactement la raison pour laquelle les applications Web semblent encombrantes ou lentes : un manque de véritable interactivité. Lorsque le bouton est enfoncé, l'application devient effectivement inutilisable jusqu'à ce que la demande qui vient d'être déclenchée reçoive une réponse. Si la requête nécessite beaucoup de traitement par le serveur, le temps d'attente peut être long (du moins dans ce monde multiprocesseur et DSL sans attente).
Les requêtes asynchrones n'attendent pas de réponse du serveur. L'application continue de s'exécuter après l'envoi de la demande. Les utilisateurs peuvent toujours saisir des données dans le formulaire Web ou même quitter le formulaire. Il n'y a pas de boules ou de sabliers qui tournent et l'application ne se fige pas sensiblement. Le serveur répond silencieusement à la demande et, une fois terminé, indique au demandeur d'origine que le travail est terminé (vous verrez dans combien de temps). Le résultat est une application qui semble moins lente et plus réactive, interactive et beaucoup plus rapide. Ce n’est qu’une partie du Web 2.0, mais c’est une partie importante. Tous les anciens composants d'interface graphique et paradigmes de conception Web ne peuvent pas surmonter le modèle requête/réponse lent et synchrone.
Envoi de requêtes
Une fois configuré avec open(), vous pouvez envoyer des requêtes. Heureusement, la méthode d'envoi des requêtes a un nom plus approprié que open() : il s'agit de send().
send() n'a qu'un seul paramètre, qui est le contenu à envoyer. Mais avant d'envisager cette méthode, rappelez-vous que vous avez déjà envoyé des données via l'URL elle-même :
var url = "/cgi-local/lookupCustomer.php?phone=" + escape(phone)
Bien que vous puissiez utiliser send() pour envoyer des données ; , Mais il est également possible d'envoyer des données via l'URL elle-même. En fait, avec les requêtes GET (qui se produisent dans environ 80 % des applications Ajax classiques), il est beaucoup plus facile d'envoyer des données à l'aide d'une URL. Si vous avez besoin d'envoyer des informations sécurisées ou du XML, vous pouvez envisager d'utiliser send() pour envoyer le contenu (les données sécurisées et les messages XML seront abordés dans les articles suivants de cette série). Si vous n'avez pas besoin de transmettre des données via send(), transmettez simplement null comme paramètre de cette méthode. Vous constaterez donc que c'est tout ce que vous devez faire dans les exemples de cet article (voir Listing 10).
Listing 10.
Fonction d'envoi de requête getCustomerInfo() {
var téléphone = document.getElementById("téléphone").value;
var url = "/cgi-local/lookupCustomer.php?phone=" + escape(phone);
request.open("GET", url, true);
request.send(null);
}
Spécifier la méthode de rappel
Il y a très peu de choses dans ce que nous faisons actuellement qui soient nouvelles, révolutionnaires ou asynchrones. Il faut admettre que le petit mot-clé "true" de la méthode open() établit une requête asynchrone. Mais à part cela, le code n'est pas différent de la programmation avec des servlets Java et JSP, PHP ou Perl. Alors, quel est le plus grand secret d’Ajax et du Web 2.0 ? Le secret réside dans une simple propriété onreadystatechange de XMLHttpRequest.
Assurez-vous d'abord de comprendre le flux de ce code (consultez le listing 10 si nécessaire). Construisez sa requête puis effectuez la requête. De plus, la requête étant asynchrone, la méthode JavaScript (getCustomerInfo() dans l'exemple) n'attend pas le serveur. Ainsi, le code continuera à s'exécuter, c'est-à-dire que la méthode se terminera et que le contrôle reviendra au formulaire. L'utilisateur peut continuer à saisir ses informations et l'application n'attend pas le serveur.
Cela soulève une question intéressante : que se passe-t-il une fois que le serveur a terminé la requête ? La réponse est que rien ne se passe, du moins pour le code actuel ! Évidemment, cela ne fonctionnera pas, le serveur a donc besoin d'une sorte d'instructions sur ce qu'il doit faire une fois qu'il a fini de traiter la requête qui lui a été envoyée via XMLHttpRequest.
Fonctions de référence en JavaScript :
JavaScript est un langage faiblement typé et vous pouvez utiliser des variables pour référencer n'importe quoi. Ainsi, si vous déclarez une fonction updatePage(), JavaScript traite également le nom de la fonction comme une variable. En d'autres termes, vous pouvez référencer la fonction dans votre code en utilisant le nom de variable updatePage.
Listing 11. Définir
la fonction de méthode de rappel getCustomerInfo() {
var téléphone = document.getElementById("téléphone").value;
var url = "/cgi-local/lookupCustomer.php?phone=" + escape(phone);
request.open("GET", url, true);
request.onreadystatechange = updatePage;
request.send(null);
}
Il est important de noter où dans le code cette propriété est définie - elle est définie avant l'appel de send(). Cette propriété doit être définie avant d'envoyer la requête afin que le serveur puisse la visualiser après avoir répondu à la requête terminée. Il ne reste plus qu'à écrire la méthode updatePage(), qui fait l'objet de la dernière section de cet article.
Le serveur de traitement répond
à la demande, l'utilisateur utilise joyeusement le formulaire Web (pendant que le serveur traite la demande) et le serveur a maintenant terminé le traitement de la demande. Le serveur examine l'attribut onreadystatechange pour déterminer la méthode à appeler. Sinon, traitez votre application comme n’importe quelle autre application, qu’elle soit asynchrone ou non. En d'autres termes, vous n'avez pas nécessairement besoin de prendre des mesures spéciales pour écrire une méthode qui répond au serveur, il vous suffit de modifier le formulaire, de laisser l'utilisateur visiter une autre URL ou de faire tout ce dont le serveur de réponse a besoin. Dans cette section, nous nous concentrons sur les réponses au serveur et sur une action typique : modifier instantanément une partie du formulaire que l'utilisateur voit.
Rappels et Ajax
Nous avons maintenant vu comment indiquer au serveur quoi faire une fois l'opération terminée : définissez la propriété onreadystatechange de l'objet XMLHttpRequest sur le nom de la fonction à exécuter. De cette façon, la fonction sera appelée automatiquement une fois que le serveur aura traité la requête. Il n’y a pas non plus besoin de s’inquiéter des paramètres de la fonction. Nous commençons par une méthode simple, présentée dans le listing 12.
Listing 12. Code de la méthode de rappel
<langage de script="javascript" type="text/javascript">
var requête = faux ;
essayer {
requête = nouveau XMLHttpRequest();
} attraper (essayerMicrosoft) {
essayer {
request = new ActiveXObject("Msxml2.XMLHTTP");
} catch (autremicrosoft) {
essayer {
request = new ActiveXObject("Microsoft.XMLHTTP");
} catch (échec) {
demande = faux ;
}
}
}
si (!request)
alert("Erreur lors de l'initialisation de XMLHttpRequest !");
function getCustomerInfo() {
var téléphone = document.getElementById("téléphone").value;
var url = "/cgi-local/lookupCustomer.php?phone=" + escape(phone);
request.open("GET", url, true);
request.onreadystatechange = updatePage;
request.send(null);
}
fonction updatePage() {
alert("Le serveur est terminé !");
}
</script>
Il émet simplement quelques avertissements simples pour vous indiquer quand le serveur a terminé sa tâche. Essayez ce code sur votre propre page Web et ouvrez-le dans un navigateur (voir le listing 8 si vous souhaitez voir le XHTML dans cet exemple). Entrez le numéro de téléphone puis quittez le champ, vous verrez une fenêtre d'avertissement contextuelle (comme le montre la figure 3), mais cliquez sur OK et elle réapparaîtra...
Figure 3. Code Ajax pour l'avertissement contextuel
Selon le navigateur, vous pouvez voir deux, trois ou même quatre avertissements avant que le formulaire ne cesse de s'afficher. Que se passe-t-il? Il s'avère que nous n'avons pas pris en compte l'état de préparation HTTP, qui constitue une partie importante du cycle requête/réponse.
État HTTP prêt
Comme mentionné précédemment, le serveur recherche la méthode à appeler dans l'attribut onreadystatechange de XMLHttpRequest après avoir terminé la requête. C'est vrai, mais incomplet. En fait, il appelle cette méthode chaque fois que l’état HTTP prêt change. Qu'est-ce que cela signifie? Vous devez d’abord comprendre l’état de préparation HTTP.
L'état HTTP prêt représente l'état ou la condition de la demande. Il est utilisé pour déterminer si la demande a été lancée, si une réponse a été reçue ou si le modèle demande/réponse a été terminé. Cela peut également aider à déterminer s’il est sécuritaire de lire le texte de réponse ou les données fournies par le serveur. Il y a cinq états de préparation à connaître dans les applications Ajax :
·0 : La requête n'a pas été émise (avant l'appel d'open()).
·1 : La requête a été établie mais pas encore envoyée (avant l'appel de send()).
·2 : La demande a été envoyée et est en cours de traitement (l'en-tête du contenu peut généralement être obtenu à partir de la réponse).
·3 : La demande a été traitée et certaines données sont généralement disponibles dans la réponse, mais le serveur n'a pas terminé la réponse.
·4 : La réponse est complète et vous pouvez accéder à la réponse du serveur et l'utiliser.
Comme pour la plupart des problèmes multi-navigateurs, ces états prêts ne sont pas utilisés de manière cohérente. Vous pourriez vous attendre à ce que l’état de préparation de la tâche passe de 0 à 1, puis à 2, puis à 3, puis à 4, mais c’est rarement le cas. Certains navigateurs ne rapportent jamais 0 ou 1 mais commencent directement par 2, puis 3 et 4. D'autres navigateurs signalent tous les statuts. D'autres signalent plusieurs fois l'état prêt 1. Comme vu dans la section précédente, le serveur appelle updatePage() plusieurs fois, et une boîte d'avertissement apparaît à chaque fois qu'il est appelé - cela peut être différent de ce qui est attendu !
Pour la programmation Ajax, le seul état qui doit être géré directement est l'état prêt 4, qui indique que la réponse du serveur est complète et que les données de réponse peuvent être utilisées en toute sécurité. Sur cette base, la première ligne de la méthode de rappel devrait ressembler au listing 13.
Listing 13. Vérification de l'état de préparation de
la fonction updatePage() {
si (requête. readyState == 4)
alert("Le serveur est terminé !");
}
Après modification, vous pouvez vous assurer que le traitement du serveur est terminé. Essayez d'exécuter la nouvelle version du code Ajax et vous ne verrez désormais le message d'avertissement affiché qu'une seule fois, comme prévu.
Codes d'état HTTP
Bien que le code du listing 13 semble correct, il y a un problème : que se passe-t-il si le serveur répond à la requête et termine le traitement mais signale une erreur ? Sachez que le code côté serveur doit comprendre qu'il est appelé par Ajax, JSP, des formulaires HTML bruts ou d'autres types de code, mais qu'il ne peut rapporter des informations qu'à l'aide de méthodes traditionnelles spécifiques au Web. Dans le monde Web, le code HTTP peut gérer divers problèmes pouvant survenir lors de la requête.
Par exemple, vous devez avoir rencontré une situation dans laquelle vous avez saisi une mauvaise demande d'URL et obtenu un code d'erreur 404, ce qui signifie que la page n'existe pas. Il ne s'agit que de l'un des nombreux codes d'erreur pouvant être reçus avec une requête HTTP (voir le lien dans Ressources pour une liste complète des codes d'état). Les numéros 403 et 401, qui indiquent que les données accessibles sont protégées ou interdites, sont également courants. Dans les deux cas, ces codes d’erreur sont obtenus à partir de la réponse complétée. En d’autres termes, le serveur a répondu à la demande (c’est-à-dire que l’état HTTP prêt est 4) mais n’a pas renvoyé les données attendues par le client.
Ainsi, en plus du statut prêt, vous devez également vérifier le statut HTTP. Le code d'état attendu est 200, ce qui signifie que tout s'est bien passé. Si l'état prêt est 4 et le code d'état est 200, vous pouvez traiter les données du serveur et les données doivent être les données demandées (plutôt que des erreurs ou d'autres informations problématiques). Par conséquent, nous devons également ajouter une vérification de statut dans la méthode de rappel, comme indiqué dans le listing 14.
Listing 14. Vérifiez
la fonction du code d'état HTTP updatePage() {
si (requête. readyState == 4)
si (request.status == 200)
alert("Le serveur est terminé !");
}
Pour ajouter une gestion des erreurs plus robuste et essayer d'éviter une complication excessive en ajoutant une ou deux vérifications de code d'état, jetez un œil à la version modifiée de updatePage() dans le listing 15.
Listing 15. Ajoutez une petite
fonction de vérification des erreurs updatePage() {
si (requête. readyState == 4)
si (request.status == 200)
alert("Le serveur est terminé !");
sinon si (request.status == 404)
alert("L'URL de la demande n'existe pas");
autre
alert("Erreur : le code d'état est " + request.status);
}
Maintenant, changez l'URL dans getCustomerInfo() en une URL inexistante et voyez ce qui se passe. Vous devriez voir un message d’avertissement indiquant que l’URL demandée n’existe pas – super ! Il est difficile de gérer toutes les conditions d'erreur, mais ce petit changement peut couvrir 80% des problèmes d'une application Web typique.
La lecture du texte de réponse
garantit désormais que la demande a été traitée (via l'état prêt), le serveur a donné une réponse normale (via le code d'état), et enfin nous pouvons traiter les données renvoyées par le serveur. Les données renvoyées sont stockées dans la propriété ResponseText de l'objet XMLHTTPRequest.
Le contenu du texte dans ResponseText, tel que le format et la longueur, est intentionnellement laissé vague. De cette façon, le serveur peut définir le texte sur n'importe quoi. Par exemple, un script peut renvoyer des valeurs séparées par les virgules, un autre utilise un tuyau (le caractère) pour séparer les valeurs, et encore un autre renvoie une longue chaîne de texte. C'est au serveur de décider où aller.
Dans l'exemple utilisé dans cet article, le serveur renvoie la dernière commande et l'adresse du client du client, séparées par un caractère de tuyau. L'ordre et l'adresse sont ensuite utilisés pour définir les valeurs des éléments dans le formulaire.
Listing 16. Gestion de
la fonction de réponse du serveur UpdatePage () {
if (request.readystate == 4) {
if (request.status == 200) {
var réponse = request.ResponSext.split ("|");
document.getElementById ("Order"). Value = Response [0];
document.getElementById ("adresse"). innerHtml =
réponse [1] .replace (/ n / g, "");
} autre
alert ("statut est" + request.status);
}
}
Tout d'abord, obtenez le ResponseText et divisez-le du tuyau à l'aide de la méthode JavaScript Split (). Le réseau résultant est placé en réponse. La première valeur dans le tableau - l'ordre précédent - est accessible avec la réponse [0] et est définie sur la valeur du champ avec ID "Ordre". La deuxième réponse de valeur [1], l'adresse du client, nécessite un peu plus de traitement. Étant donné que les lignes de l'adresse sont séparées par des séparateurs de ligne normaux (caractères " n"), le code doit utiliser à la place des séparateurs de ligne de style XHTML <BR />. Le processus de remplacement est effectué à l'aide de la fonction Remplace () et des expressions régulières. Enfin, le texte modifié est utilisé comme HTML intérieur dans le formulaire HTML Div. Le résultat est que le formulaire se met soudainement à jour avec les informations du client, comme le montre la figure 4.
Figure 4. Formulaire de couche après avoir reçu les données des clients
Avant de terminer cet article, je voudrais introduire un autre attribut important de XMLHTTPREQUEST, ResponseXML. Cette propriété contient (comme vous l'avez peut-être deviné) la réponse XML si le serveur choisit d'utiliser une réponse XML. Le traitement des réponses XML est très différent du traitement du texte ordinaire, impliquant l'analyse, le modèle d'objet de document (DOM) et d'autres problèmes. XML sera couvert plus loin dans un article ultérieur. Mais comme ResponseXML est généralement discuté avec ResponseTeXt, il mérite une mention ici. Pour de nombreuses applications AJAX simples, ResponseText suffira, mais vous verrez bientôt que XML peut également être bien géré avec les applications AJAX.
Conclusion
Vous pouvez être un peu fatigué de XMLHTTPRequest. Mais vous utiliserez cet objet encore et encore dans chaque page et application que vous écrivez à l'aide d'Ajax. Franchement, il y a quelque chose à dire pour XMLHttpRequest. Le prochain article présentera comment utiliser la publication et obtenir des demandes pour définir des en-têtes de contenu dans les demandes et lire les en-têtes de contenu à partir des réponses du serveur, et comprendre comment coder les demandes et traiter XML dans le modèle de demande / réponse.
Plus tard, nous présenterons des boîtes à outils AJAX courantes. Ces boîtes à outils masquent en fait de nombreux détails décrits dans cet article, ce qui facilite la programmation de l'Ajax. Vous vous demandez peut-être pourquoi vous devez coder les détails de bas niveau alors qu'il y a tellement de boîtes à outils. La réponse est qu'il est difficile de repérer des problèmes dans une demande sans savoir ce que fait la demande.
Alors n'ignorez pas les détails ou parcourez simplement, et si quelque chose ne va pas avec cette boîte à outils pratique et magnifique, vous n'aurez pas à vous gratter la tête ou à envoyer un e-mail à l'aide. Si vous comprenez comment utiliser XMLHttpRequest directement, vous trouverez facile de déboguer et de résoudre les problèmes les plus étranges. Une boîte à outils n'est bonne que si vous le laissez résoudre vos problèmes.
Veuillez donc vous familiariser avec XMLHttpRequest. En fait, si vous avez un code AJAX qui utilise la boîte à outils, essayez de le réécrire à l'aide de l'objet XMLHTTPRequest et de ses propriétés et méthodes. C'est un bon exercice pour vous aider à mieux comprendre les principes.
Le prochain article discutera de cet objet, explorant certaines de ses propriétés les plus intéressantes (telles que ResponseXML), et comment utiliser les demandes de poste et envoyer des données dans différents formats. Veuillez commencer à écrire du code et nous en discuterons à nouveau dans un mois.