Asynchronous – JavaScript - XML

Transcription

Asynchronous – JavaScript - XML
AJAX
Asynchronous – JavaScript - XML
Rédacteur
Version
Date
: Morel Alexandre
: 1.2
: 08 novembre 2005
Alexandre Morel
Ajax
Tables des matières
Introduction _________________________________________ 3
L'objet XMLHttpRequest ____________________________________ 3
Qu'est-ce qu'AJAX ? _______________________________________ 3
Utilisation ___________________________________________ 4
Étape 1 - Lancement d'une requête http _______________________ 4
Étape 2 - Gestion de la réponse du serveur _____________________ 7
Étape 3 - Utilisation de la réponse du serveur ___________________ 8
Étape 4 - Un exemple simple ________________________________ 9
Étape 5 - Travailler avec des réponses XML ____________________ 12
Conclusions _________________________________________ 13
Avantages______________________________________________ 13
Inconvénients___________________________________________ 13
Annexes ___________________________________________ 14
Propriétés et méthodes ___________________________________ 14
Propriétés _______________________________________________________ 14
Méthodes ________________________________________________________ 14
Code d'état http _________________________________________ 16
2/16
Alexandre Morel
Ajax
Introduction
L'objet XMLHttpRequest
Créé par Microsoft pour Internet Explorer, l'objet XMLHttpRequest a été adopté par les
navigateurs Mozilla, Konqueror, Safari et récemment Opéra. Bien que largement
implémentée dans les navigateurs récents, cette technologie n'est pas un standard
du W3C , lequel propose des fonctionnalités similaires à travers la recommandation
Document Object Model (DOM) Level 3 Load and Save Specification.
Cet objet permet de faire des requêtes HTTP afin de récupérer des données au format
XML qui pourront être intégrées à un document. Cela peut être très utile pour mettre à
jour des données sans pour autant recharger la page.
Qu'est-ce qu'AJAX ?
L'utilisation de XMLHttpRequest fait immédiatement penser à AJAX, c'est un nouveau
terme inventé récemment pour désigner deux puissantes fonctionnalités du JavaScript
qui existent depuis plusieurs années, mais qui sont restées inaperçues de nombreux
développeurs Web jusqu'il y a peu. Depuis, des applications comme Gmail, Google
suggest et Google Maps sont devenues monnaie courante.
Ces deux fonctionnalités de JavaScript sont les possibilités de :
•
•
Faire des requêtes vers le serveur sans avoir à recharger la page.
Parcourir et travailler avec des documents XML ou autres.
Le terme AJAX est un acronyme en anglais. Le A est pour « asynchronous »
(asynchrone), ce qui signifie que vous pouvez faire une requête HTTP vers le serveur et
faire d'autres choses en attendant que la réponse arrive. JA est pour « JavaScript » et X
est pour « XML ».
Cette architecture client/serveur consiste en effet à découper une application web de la
façon suivante :
•
•
•
•
•
une présentation utilisant XHTML et CSS.
la manipulation dynamique des pages à travers DOM.
la manipulation des données avec XML et XSLT.
l'échange des données de manière asynchrone avec XMLHttpRequest.
le tout étant assemblé avec du Javascript.
Les éléments clés de cette architecture sont la séparation en couches distinctes des
éléments du client à l'aide de technologies standardisées et les échanges asynchrones de
données au format XML.
3/16
Alexandre Morel
Ajax
Utilisation
Étape 1 - Lancement d'une requête http
Afin de faire une requête HTTP vers le serveur à l'aide de JavaScript, il faut disposer
d'une instance d'une classe fournissant cette fonctionnalité. Une telle classe a d'abord été
introduite dans Internet Explorer sous la forme d'un objet ActiveX appelé XMLHTTP. Par la
suite, Mozilla, Safari et d'autres navigateurs ont suivi en implémentant une classe
XMLHttpRequest qui fournit les mêmes méthodes et propriétés que l'objet ActiveX
original de Microsoft.
Par conséquent, pour créer une instance de la classe (un objet) fonctionnant sur
plusieurs navigateurs, vous pouvez utiliser :
/* On crée l’instance de l’objet XMLHTTPRequest */
var mon_objet = new object ;
/* Si c’est Mozilla/Firefox/Nescape/opera/safari */
if(window.XMLHttpRequest)
mon_objet = new XMLHttpRequest();
/* Si c’est Internet Explorer */
else if(window.ActiveXObject)
mon_objet = new ActiveXObject("Microsoft.XMLHTTP");
/* Si aucun navigateur compatible avec XMLHttpRequest, on le signal */
else
{
alert("Votre navigateur ne supporte pas les objet XMLHTTPRequest…");
return;
}
Certaines versions de certains navigateurs Mozilla ne fonctionneront pas correctement si
la réponse du serveur n'a pas un en-tête de type MIME XML. Pour les satisfaire, vous
pouvez utiliser un appel de fonction supplémentaire pour écraser l'en-tête envoyé par le
serveur, juste au cas où il ne s'agit pas de text/xml, comme ceci :
mon_objet.overrideMimeType("text/xml");
La chose suivante à faire est de décider ce que vous voulez faire après avoir reçu la
réponse du serveur. À ce stade, vous devez juste dire à l'objet de requête HTTP quelle
fonction JavaScript devra effectuer le travail d'analyse de la réponse. Cela se réalise en
assignant à la propriété onreadystatechange de l'objet le nom de la fonction JavaScript
que vous envisagez d'utiliser, comme ceci :
4/16
Alexandre Morel
Ajax
mon_objet.onreadystatechange = nomDeLaFonction;
Notez qu'il n'y a pas de parenthèses après le nom de la fonction, ni de paramètres
fournis. Par ailleurs, au lieu de donner un nom de fonction, vous pouvez également
utiliser la technique JavaScript de définition de fonctions au vol, et spécifier directement
les actions à effectuer sur la réponse, comme ceci :
mon_objet.onreadystatechange = function()
{
/* instructions de traitement de la réponse */
};
Ensuite, après avoir déclaré ce qui se passera lorsque la réponse sera reçue, il s'agit de
lancer effectivement la requête. Il faut pour cela appeler les méthodes open() et send()
de la classe de requête HTTP, comme ceci :
/* on spécifie la méthode de transmission des données, l'URL et le mode de transmission de la
requête */
mon_objet.open("GET", "ma_page.php", true);
mon_objet.send(null);
Le premier paramètre de l'appel à open() est la méthode de requête HTTP –
GET, POST, HEAD ou toute autre méthode que vous voulez utiliser et est
gérée par le serveur. Laissez le nom de la méthode en majuscules comme
spécifié par la norme HTTP , autrement certains navigateurs (comme Firefox)
peuvent ne pas procéder à la requête.
Le second paramètre est l'URL de la page dont vous faites la requête. Pour
des raisons de sécurité, il n'est pas possible d'appeler des pages se situant
sur un autre domaine.
Le troisième paramètre précise si la requête est asynchrone. Si, mis à TRUE,
l'exécution de la fonction JavaScript se poursuivra en attendant l'arrivée de la
réponse du serveur.
5/16
Alexandre Morel
Ajax
Le paramètre de la méthode send() peut être n'importe quelle donnée que vous voulez
envoyer au serveur en cas d'utilisation de la méthode POST. Les données doivent être
sous la forme d'une chaîne de requête, comme :
/* Variable qui contient les données */
var donnee = "variable1=valeur1?variable2=valeur2";
/* On envoit la requête avec les données */
mon_objet.send(donnee);
Exemple avec GET :
/* Variable qui contient les données */
var donnee = "variable1=valeur1?variable2=valeur2";
/* les données à transmettre sont concaténées à l'URL */
mon_objet.open("GET", "ma_page.php?"+donnee, true);
/* On envoie la requête */
mon_objet.send(null);
Exemple avec POST :
/* Variable qui contient les données */
var donnee = "variable1=valeur1?variable2=valeur2";
mon_objet.open("POST", "ma_page.php", true);
/* On précise l'encodage en spécifiant l'en-tête adéquat (seulement avec POST) */
mon_objet.setRequestHeader("Content-type","application/x-www-form-urlencoded");
/* On envoie la requête avec les données */
mon_objet.send(donnee);
6/16
Alexandre Morel
Ajax
Étape 2 - Gestion de la réponse du serveur
Souvenez-vous que lors de l'envoi de la requête, vous aviez fourni le nom d'une fonction
JavaScript conçue pour traiter la réponse.
Voyons maintenant ce que cette fonction doit faire. Tout d'abord, elle doit vérifier l'état
de la requête. Si cet état a une valeur de 4, cela signifie que la réponse du serveur a été
reçue dans son intégralité et qu'elle peut maintenant être traitée.
if (mon_objet.readyState == 4)
{
/* tout va bien, la réponse a été reçue */
}
else
{
/* pas encore prête */
}
Voici la liste complète des valeurs de readyState :
0 (non initialisée)
1 (en cours de chargement)
2 (chargée)
3 (en cours d'interaction)
4 (terminée)
La seconde chose à vérifier est le code d'état HTTP de la réponse du serveur. Tous
les codes possibles sont listés en annexe. Cela nous permet de gérer les différentes
erreurs possible. Exmple avec une réponse 404 (page non trouvée).
if (mon_objet.readyState == 4)
{
/* tout va bien, la réponse a été reçue */
}
else
{
if (mon_objet.status == 404)
{
/* la page n'a pas été trouvé */
}
}
7/16
Alexandre Morel
Ajax
Étape 3 - Utilisation de la réponse du serveur
Maintenant que vous avez vérifié l'état de la requête et le code d'état HTTP de la
réponse, vous pouvez faire ce que vous voulez des données envoyées par le serveur.
Il existe deux manières d'accéder à ces données :
http_request.responseText – renvoie la réponse du serveur sous
la forme d'une chaîne de texte, Exemple :
/* Variable qui contient la commande */
var donnee = "commande=1&type=veste&couleur=rouge&taille=XL";
mon_objet.open("POST", "creation_facture.php", true);
/* On spécifie la fonction à exécuter */
mon_objet.onreadystatechange = function()
{
if (mon_objet.readyState == 4)
{
var facture = mon_objet.reponseText;
/* on affiche la facture */
alert(facture);
}
}
/* On précise l'encodage en spécifiant l'en-tête adéquat (seulement avec POST) */
mon_objet.setRequestHeader("Content-type","application/x-www-form-urlencoded");
/* On envoit la requête avec les données */
mon_objet.send(donnee);
http_request.responseXML – renvoie la réponse sous la forme
d'un objet XMLDocument que vous pouvez parcourir à l'aide des
fonctions DOM de JavaScript (nous verrons cela plus tard).
8/16
Alexandre Morel
Ajax
Étape 4 - Un exemple simple
Mettons tout cela ensemble et effectuons une requête HTTP simple. Notre JavaScript
demandera une reponse php, personne.php, qui contiendra le texte« Nom: et Prenom:»,
et nous afficherons le contenu dans une case d'un tableau html avec innerHTML).
Fichier HTML (index.html) :
<html>
<head>
<title>Personnes</title>
<script LANGUAGE="Javascript1 1.2" src="javascript.js"></script>
<head>
<body>
<table>
<tr>
<td name="reponse"><a
href="javascript:mapage("AM")">AM</a></td>
</tr>
</table>
</body>
</html>
Fichier javascript (javascript.js)
/* On crée l’instance de l’objet XMLHTTPRequest */
var mon_objet = null;
/* Si c’est Mozilla/Firefox/Nescape/opera/safari */
if(window.XMLHttpRequest)
mon_objet = new XMLHttpRequest();
/* Si c’est Internet Explorer */
else if(window.ActiveXObject)
mon_objet = new ActiveXObject("Microsoft.XMLHTTP");
/* Si aucun navigateur compatible avec XMLHttpRequest, on le signal */
else
{
alert("Votre navigateur ne supporte pas les objet XMLHTTPRequest…");
return;
}
/* Fonction à executer quand on clique sur le lien AM */
function mapage(ma_valeur)
{
mon_objet.open("POST", "personne.php", true);
/* On spécifie la fonction à exécuter */
mon_objet.onreadystatechange = function()
{
if (mon_objet.readyState == 4)
9/16
Alexandre Morel
Ajax
{
/* On exécute la fonction avec paramètre réponse */
affiche(mon_objet.reponseText);
}
}
/* On précise l'encodage en spécifiant l'en-tête adéquat (seulement avec POST) */
mon_objet.setRequestHeader("Content-type","application/x-www-form-urlencoded");
/* On définit les variables a envoyer */
if (ma_variable=="AM")
var donnee = "nom=Morel&prenom=Alexandre";
else
var donnee = "nom=Inconnu&prenom=Inconnu";
/* On envoie la requête avec les données */
mon_objet.send(donnee);
}
/* Pour remplacer le texte dans le document */
function affiche(texte)
{
/* on cherche la version du navigateur */
var ns4 = (document.layers)? true:false;
/* Nescape 4 */
var ie4 = (document.all)? true:false;
/* Internet Eplorer 4 */
var dom = (document.getElementById)? true:false;
/* Nescape 6 ou Internet Eplorer 6 */
if(dom)
{
document.getElementById("reponse").innerHTML = texte;
return;
}
else if(ie4)
{
document.all["reponse"].innerHTML = texte;
return;
}
else if(ns4)
{
with (eval('document.'+"reponse"+'.document'))
{
open();
write(texte);
close();
}
return;
}
}
10/16
Alexandre Morel
Ajax
Fichier php (personne.php)
/* On défini le type de fichier */
Header("Content-type: text/html; charset=iso-8859-1");
/* on affiche le nom */
echo 'Nom : '.$_POST['nom'];
/* on affiche le prénom */
echo 'Prénom : '.$_POST['prenom'];
Dans cet exemple :
L'utilisateur clique sur le lien « AM » dans le navigateur.
ceci appelle la fonction mapage() avec en paramètre les initiales (AM)
cela exécute le fichier personne.php.
qui renvoie le texte mis en forme.
quand on reçoit la réponse, on exécute affiche()
qui remplace la case lien « AM » par le résultat de reponseText
11/16
Alexandre Morel
Ajax
Étape 5 - Travailler avec des réponses XML
Dans l'exemple précédent, après que la réponse à la requête HTTP ait été reçue, nous
avons utilisé la propriété reponseText de l'objet de requête, et celle-ci renvoyait le
contenu du fichier. Essayons maintenant la propriété reponseXML.
Tout d'abord, créons un document XML valide qui sera l'objet de la requête. Le document
(test.xml) contient ce qui suit :
<?xml version="1.0" ?>
<root>
Je suis un test.
</root>
Dans le script, il est juste nécessaire de remplacer la ligne de requête par :
...
onclick="makeRequest('test.xml')">
...
Ensuite, dans alertContents(), il
faut
remplacer la ligne affichant
un
message
alert(mon_objet.responseText), par :
/* on crée un objet qui contiendra le document XML */
var DocXml = http_request.responseXML;
/* on crée une variable qui contiendra le noeud root */
var noeud = DocXml.getElementsByTagName('root').item(0);
/* on affiche le premier noeud root trouver */
alert(noeud.firstChild.data);
De cette façon, nous avons pris l'objet XMLDocument donné par responseXML et nous
avons utilisé des méthodes DOM pour accéder à certaines données contenues dans le
document XML.
12/16
Alexandre Morel
Ajax
Conclusions
Avantages
•
•
•
Diminution de la bande passante : seules les données sont chargées et non plus
tout le document.
Interactivité accrue : plus de rechargement de la page.
Rationnalisation du code : des routines (de vérification par exemple) n'ont plus à
être écrites et maintenues dans deux langages (côté client et côté serveur).
Inconvénients
•
•
•
•
•
Ne fonctionne pas sans Javascript, ni dans les navigateurs les plus anciens.
Ne fonctionne qu'avec HTTP : il est impossible de récupérer des données sur un
disque local (ce qui est normal).
Impossible d’envoyer un fichier en utilisant AJAX, défini pour des raisons de
sécurité évidente (On pourrai prendre un fichier sans prévenir utilisateur,…)
Les requêtes en dehors du domaine provoquent un avertissement de sécurité.
Peut empêcher des comportements habituels du navigateur :
o Marques-pages et liens vers la page.
o Enregistrement des pages.
o Bouton retour.
o Difficulté de référencement
13/16
Alexandre Morel
Ajax
Annexes
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
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/xmlsdk/html/xmobjpmeserverxmlhttp.asp
Propriétés
.onreadystatechange
: Spécifie la fonction à appeler lorsque la propriéte
readyState varie.
Lecture/Ecriture
.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
. statusText
: message accompagnant le code de réponse.
Lecture seule
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.
14/16
Alexandre Morel
Ajax
.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.
eval(mon_object.responseText);
Permet d’exécuter la réponse si elle est sous forme javascript
15/16
Alexandre Morel
Ajax
Code d'état http
100
101
200
201
202
203
204
205
206
300
301
302
303
304
305
307
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
500
501
502
503
504
505
Continue
Switching protocols
OK
Created
Accepted
Non-Authoritative Information
No Content
Reset Content
Partial Content
Multiple Choices
Moved Permanently
Found
See Other
Not Modified
Use Proxy
Temporary Redirect
Bad Request
Unauthorized
Payment Required
Forbidden
Not Found
Method Not Allowed
Not Acceptable
Proxy Authentication Required
Request Timeout
Conflict
Gone
Length Required
Precondition Failed
Request Entity Too Large
Request-URI Too Long
Unsupported Media Type
Requested Range Not Suitable
Expectation Failed
Internal Server Error
Not Implemented
Bad Gateway
Service Unavailable
Gateway Timeout
HTTP Version Not Supported
16/16

Documents pareils