Ajax : un premier appel avec l'objet XMLHttpRequest
7 janvier 2007 —Pour réaliser un appel Ajax, vous avez besoin de trois éléments :
- Une page HTML, qui contiendra le nécessaire pour déclencher l'appel Ajax - et qui permettra la prise en compte du résultat[1].
- Quelques lignes de Javascript, pour réaliser l'appel et la récupération du résultat
- Un programme côté serveur, qui sera chargé du traitement - j'utiliserai du PHP[2] dans mes exemples.
Éventuellement, vous pouvez aussi :
- Utiliser une feuille de style CSS
- Intégrer le code Javascript directement à la page HTML
Page HTML
Pour notre exemple, la page HTML qui intégrera des fonctionnalités Ajax permet :
- L'appel à une portion de code Javascript qui réalisera l'appel ; Ceci peut être fait lors du clic sur un lien, par exemple
- L'affichage du résultat de l'appel ; dans un élément
div
, par exemple
Voici le lien qui appellera la fonction JS déclenchant l'appel :
<a href="" onclick="gestionClic(); return false;">
Cliquez ici !
</a>
Et le bloc au sein duquel sera affiché le résultat de celui-ci :
<div id="resultat">
valeur avant l'appel Ajax
</div>
Javascript : Appel Ajax
Un appel Ajax demande plusieurs étapes :
- Instancier un objet XMLHttpRequest
- L'initialiser
- Définir quelle fonction devra être appelée lors d'un événement sur cet objet
- Et enfin, déclencher l'appel
Instanciation d'un objet XMLHttpRequest
Un appel Ajax se fait en utilisant une instance de l'objet XMLHttpRequest.
Sous les navigateurs récents[3], une telle instance s'obtient de la manière suivante :
var http = new XMLHttpRequest();
Sous Internet Explorer 6, par contre, cet objet est un contrôle ActiveX ; le code suivant permet d'en obtenir une instance :
var http = new ActiveXObject("Microsoft.XMLHTTP");
Par soucis de compatibilité entre navigateurs, on utilise souvent une fonction de ce genre, qui se charge de créer une instance d'object XMLHttpRequest :
function createRequestObject()
{
var http;
if (window.XMLHttpRequest)
{ // Mozilla, Safari, IE7 ...
http = new XMLHttpRequest();
}
else if (window.ActiveXObject)
{ // Internet Explorer 6
http = new ActiveXObject("Microsoft.XMLHTTP");
}
return http;
}
Note : dans un cas réel, il faudrait gérer le cas où cette fonction échoue...
Paramétrage de l'appel
Une fois que l'on dispose d'une instance d'objet XHR[4], il faut paramétrer l'appel. Pour cela, on utilise la méthode open :
objetXMLHttpRequest.open(methode, urlEtParams, async);
Voici la signification des trois paramètres attendus :
- methode : en général,
'GET'
ou'POST'
. Détermine quel type de requête HTTP sera utilisée pour l'appel Ajax. - urlEtParams : l'URL du programme qui sera exécuté, éventuellement suivie d'une liste de paramètre, si l'on est en GET.
- async :
true
pour déclencher un appel en arrière-plan (asynchrone)[5] ;false
pour un appel synchrone bloquant le navigateur.
Par exemple, on pourrait utiliser une portion de code telle celle-ci :
http.open('GET', 'mon-script.php', true);
Préparer la récupération des informations renvoyées par l'appel
Ceci fait, vous avez la possibilité de définir quelle fonction sera appelée lorsqu'un événement se produit sur votre instance d'objet XHR - quand il se passe quelque chose en rapport avec votre appel Ajax, donc.
En supposant que nous avons défini une fonction nommée handleAJAXReturn
:
http.onreadystatechange = handleAJAXReturn;
Lancer l'appel
Enfin, nous pouvons lancer l'appel Ajax, à l'aide de la méthode send
:
http.send(null);
Cette méthode prend un paramètre, qui peut valoir :
null
, dans le cas où l'appel se fait en GET- Une liste de paramètres, de la forme
'param1=valeur1¶m2=valeur2¶m3=valeur3'
, quand l'appel se fait en POST
Côté serveur : programme appelé
Côté serveur, nous pouvons effectuer les traitements sans avoir à nous soucier du fait que le programme/script est déclenché via un appel Ajax.
Notamment, nous pouvons utiliser les données passées en GET/POST[6].
Prenons l'exemple le plus simple qui soit : un script PHP ne faisant rien de plus qu'afficher un message à l'écran, dans le cas où il est appelé directement :
<?php
echo 'coucou';
?>
Un point est à prendre en compte : de manière générale, lors que vous réalisez un appel Ajax, vous souhaitez que le programme côté serveur soit plus dynamique que ça : qu'il renvoie des données dépendant des paramètres passés, par exemple.
Il est donc parfois recommandé de désactiver la mise en cache, de manière à ce que le navigateur soit contraint à actualiser les données lorsque l'appel se réalise[7].
Pour cela, en PHP, voici le genre de code qu'il faut utiliser :
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-cache, must-revalidate');
header('Pragma: no-cache');
Javascript : Résultat de l'appel Ajax
Enfin, côté client, nous pouvons lire le résultat de l'appel Ajax, dans le corps de la fonction handleAJAXReturn
, que nous avons défini comme étant celle appelée lorsqu'un événement se produit sur notre objet XHR.
Au sein de cette fonction, nous pouvons utiliser l'attribut readyState
de l'objet XMLHttpRequest : s'il vaut 4
, c'est que la fonction est appelée au moment du retour de l'appel Ajax.
Nous pouvons aussi utiliser l'attribut status
, qui a pour valeur le code HTTP renvoyé par le serveur : 200 en cas de succès, 404 si l'URL appelée n'a pas été trouvée, 403 en cas d'accès non autorisé, ...
Les tests à effectuer sont donc, au minimum, les suivants :
if (http.readyState == 400 && http.status == 200)
{
// Appel Ajax terminé, et bien passé
}
Le résultat renvoyé par le serveur est disponible via deux propriétés de l'objet XHR :
responseText
: la réponse du serveur, sous forme d'une chaîne de caractèresresponseXML
: la réponse du serveur, sous forme d'un objet XML, dans le cas où le serveur a renvoyé du XML.
Avec le programme PHP reproduit plus haut, on pourrait afficher "coucou" - le message renvoyé - de la manière suivante :
alert(http.responseText);
Un exemple complet
Pour terminer, voici un ensemble HTML/Javascript/PHP permettant de reproduire les principes présentés dans ce billet :
Tout d'abord, la page HTML cliente :
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<title>AJAX : Exemple de client</title>
<script type="text/javascript" src="ajax.js"></script>
</head>
<body>
<p>
<a href="" onclick="gestionClic(); return false;">
Cliquez ici !
</a>
</p>
<div id="resultat"> </div>
</body>
</html>
Puis, le code Javascript permettant de gérer l'appel et l'obtention des informations retournées :
var http; // Notre objet XMLHttpRequest
function createRequestObject()
{
var http;
if (window.XMLHttpRequest)
{ // Mozilla, Safari, IE7 ...
http = new XMLHttpRequest();
}
else if (window.ActiveXObject)
{ // Internet Explorer 6
http = new ActiveXObject("Microsoft.XMLHTTP");
}
return http;
}
function gestionClic()
{
http = createRequestObject();
http.open('GET', './mon-script.php', true);
http.onreadystatechange = handleAJAXReturn;
http.send(null);
}
function handleAJAXReturn()
{
if (http.readyState == 4)
{
if (http.status == 200)
{
alert(http.responseText);
document.getElementById('resultat').innerHTML = http.responseText;
}
else
{
alert('Pas glop pas glop');
}
}
}
Et enfin, le programme PHP exécuté via l'appel Ajax :
<?php
echo 'coucou';
?>
Vous noterez que ce que nous avons développé ici n'utilise pas XML ; il ne s'agit donc pas d'AJAX[8], pas plutôt d'AHAH. D'où l'écriture généralement utilisée : "Ajax", et non "AJAX" - comme je l'indiquait en note d'un Billet précédent.
Notes
[1] Cette page peut être générée dynamiquement côté serveur, bien entendu.
[2] car fréquemment répandu, compréhensible par la plupart des développeurs, installable en local gratuitement, et libre
[3] Mozilla Firefox, Konqueror/Safari, Opera, Internet Explorer 7, en particulier
[4] Fréquemment utilisé pour XMLHttpRequest
[5] le A de Ajax
[6] Et devons les considérer comme non-securisées, de la même façon que lorsque notre page est appelée de manière traditionnelle
[7] Ceci étant en particulier vrai pour Internet Explorer
[8] Asynchronous Javascript And XML : Attention aux majuscules !