![]() ![]() Méthode |
![]() ![]() Internet Explorer |
![]() ![]() Firefox |
![]() ![]() Opera |
![]() ![]() Google Chrome |
![]() ![]() Safari |
---|---|---|---|---|---|
XMLHttpRequest |
Oui |
Oui |
Oui |
Oui |
Oui |
Le principe de fonctionnement d'XMLHttpRequest est d'envoyer une requête HTTP vers le serveur, et une fois la requête envoyée, les données renvoyées par le serveur peuvent être récupérées. Pour ce faire, il faut disposer d'un objet disposant de cette fonctionnalité. Cet objet a été développé par Microsoft et implémenté dans Outlook puis dans Internet Explorer 5.5 en tant que contrôle ActiveX. Microsoft l'avait à l'époque nommé XMLHTTP.
Par la suite, les autres navigateurs suivirent et implémentèrent un objet appelé XMLHttpRequest. Cet objet fut implémenté avec les mêmes méthodes que celle d'XMLHTTP de Microsoft. Plus tard, XMLHttpRequest fut proposé au W3C en vue de devenir un standard.
A l'heure actuelle, les navigateurs récents (IE7, FF2, Opera 9, Safari...) implémentent tous cet objet.
Pour instancier (créer, déclarer) un
objet XHR, on procède de la même façon que pour n'importe quel objet JavaScript à savoir avec le mot-clé
new
:
var xhr = new XMLHttpRequest();
Les versions d'Internet Explorer inférieures à la version 7
requièrent toujours une instanciation via un contrôle
ActiveX
. Il y a deux façons d'instancier un objet XHR avec un contrôle ActiveX et elles dépendent de la version
d'XMLHTTP utilisée. Pour faire simple, on va utiliser un
try...catch
, l'instanciation indiquée dans le
try
étant la plus récente :
try {
var xhr = new ActiveXObject("Msxml2.XMLHTTP");
} catch(e) {
var xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
Pour faire un script homogène, rassemblons ce code en un seul, en prenant soin de tester la prise en charge des différentes méthodes d'instanciation :
var xhr = null;
if (window.XMLHttpRequest || window.ActiveXObject) {
if (window.ActiveXObject) {
try {
xhr = new ActiveXObject("Msxml2.XMLHTTP");
} catch(e) {
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
} else {
xhr = new XMLHttpRequest();
}
} else {
alert("Votre navigateur ne supporte pas l'objet XMLHTTPRequest...");
return;
}
Par la suite, j'utiliserai une fonction qui retournera l'objet XMLHttpRequest instancié, ce sera plus simple :
function getXMLHttpRequest() {
var xhr = null;
if (window.XMLHttpRequest || window.ActiveXObject) {
if (window.ActiveXObject) {
try {
xhr = new ActiveXObject("Msxml2.XMLHTTP");
} catch(e) {
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
} else {
xhr = new XMLHttpRequest();
}
} else {
alert("Votre navigateur ne supporte pas l'objet XMLHTTPRequest...");
return null;
}
return xhr;
}
Par la suite, pour instancier un objet XHR, il suffira de faire :
var xhr = getXMLHttpRequest();
Dans un premier temps, il faut définir les modalités d'envoi
avec la méthode open
, et on l'enverra ensuite avec la
méthode send
:
var xhr = getXMLHttpRequest(); // Voyez la fonction getXMLHttpRequest() définie dans la partie précédente
xhr.open("GET", "handlingData.php", true);
xhr.send(null);
open
s'utilise
de cette façon : open(sMethod, sUrl, bAsync)
sMethod
: la méthode de transfert : GET ou POST;
sUrl
: la page qui donnera suite à la requête. Ça peut être une
page dynamique (PHP, CFM, ASP) ou une page statique (TXT, XML...);
bAsync
: définit si le mode de transfert est asynchrone ou non
(synchrone). Dans ce cas, mettez true
. Ce paramètre est
optionnel et vaut true
par défaut, mais il est courant
de le définir quand même (je le fais par habitude).
Si vous utilisez la méthode POST, vous devez absolument changer
le type MIME de la requête avec la méthode setRequestHeader
,
sinon le serveur ignorera la requête :
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
Vous avez la possibilité de passer des variables au serveur. Suivant la méthode d'envoi utilisée une petite différence fait son apparition.
Dans le cas de GET les variables sont transmises directement dans l'URL :
xhr.open("GET", "handlingData.php?variable1=truc&variable2=bidule", true);
xhr.send(null);
Pour POST, il faut spécifier les variables dans l'argument de
send
:
xhr.open("POST", "handlingData.php", true);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.send("variable1=truc&variable2=bidule");
Avant de passer des variables, il est important de les protéger
pour conserver les caractères spéciaux et les espaces. Pour cela, utilisez la fonction globale
encodeURIComponent
, comme ceci :
var sVar1 = encodeURIComponent("contenu avec des espaces");
var sVar2 = encodeURIComponent("je vois que vous êtes un bon élève... oopa !");
xhr.open("GET", "handlingData.php?variable1=" + sVar1 + "&variable2= " + sVar2, true);
xhr.send(null);
Dans mon exemple, la page handlingData.php reçoit la requête. Cette page est une page PHP, elle est donc dynamique, mais ce n'est pas obligatoire, il peut s'agir d'un fichier TXT ou même XML !
Cette page se comporte comme une page PHP normale, il n'y a rien de spécifique. La récupération des variables se fait d'une façon classique (via $_GET ou $_POST, suivant la méthode d'envoi) et il ne faut pas perdre de vue de sécuriser la page, car un petit malin pourrait l'appeler directement sans passer par l'appel via XMLHttpRequest (il peut donc mettre directement l'URL de la page) :
<?php
header("Content-Type: text/plain"); // Utilisation d'un header pour spécifier le type de contenu de la page. Ici, il s'agit juste de texte brut (text/plain).
$variable1 = (isset($_GET["variable1"])) ? $_GET["variable1"] : NULL;
$variable2 = (isset($_GET["variable2"])) ? $_GET["variable2"] : NULL;
if ($variable1 && $variable2) {
// Faire quelque chose...
echo "OK";
} else {
echo "FAIL";
}
?>
Ce script ne fait évidemment rien d'intéressant, il vérifie juste si les deux variables sont renseignées. Si elles le sont, il écrit OK, et si elles ne le sont pas il écrit FAIL. C'est très important d'écrire quelque chose, car XMLHttpRequest va être capable de récupérer ce qui a été écrit, sous forme de texte brut (comme dans cet exemple) ou sous forme d'arbre XML. En écrivant OK ou FAIL, on pourra alors vérifier si le script a été correctement exécuté.
Comme je l'ai laissé entendre, il est possible d'utiliser des fichiers statiques. Dans le cas d'un fichier de texte (TXT), l'entièreté du texte sera récupéré, et s'il s'agit d'un fichier XML, on pourra récupérer la structure XML et l'utiliser directement.
Dans tous les cas, il faudra préciser dans quel format les données devront être récupérées. C'est ce que nous allons faire maintenant.
Récapitulons : en 1, on a envoyé la requête, et en 2 la requête a trouvé des données à récupérer (les données fournies par le fichier PHP, TXT ou XML).
Il faut savoir que quand on envoie une requête HTTP via XMLHttpRequest, celle-ci passe par plusieurs états différents :
0
: L'objet XHR a été créé, mais pas encore initialisé (la méthode
open
n'a pas encore été appelée)
1
: L'objet XHR a été créé, mais pas encore envoyé (avec la méthode
send
)
2
: La méthode send
vient d'être appelée
3 : Le serveur traite les informations et a commencé à renvoyer des données
4 : Le serveur a fini son travail, et toutes les données sont réceptionnées
En vue de cela, il va donc nous falloir détecter les
changements d'état pour savoir où en est la requête. Pour cela, on va utiliser la propriété
onreadystatechange
, et à chaque changement d'état (state
en anglais), on regardera lequel il s'agit :
var xhr = getXMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && (xhr.status == 200 || xhr.status == 0)) {
alert("OK"); // C'est bon \o/
}
};
xhr.open("GET", "handlingData.php", true);
xhr.send(null);
On utilise readyState
pour connaître l'état de la requête. En addition, nous devons aussi vérifier le code d'état (comme le fameux
code 404 pour les pages non trouvées ou le code 500 pour l'erreur de serveur) de la requête, pour vérifier
si tout s'est bien passé. Pour cela, on utilise la propriété status
.
Si elle vaut 200 ou 0 (aucune réponse, pratique pour les tests en local,
sans serveur d'évaluation), tout est OK.
Rien de plus simple, il suffit d'utiliser une des deux propriétés disponibles :
responseText
: pour récupérer les données sous
forme de texte brut
responseXML
: pour récupérer les données sous
forme d'arbre XML
alert
simpleL'utilisation est assez simple, il suffit de procéder comme ceci :
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && (xhr.status == 200 || xhr.status == 0)) {
alert(xhr.responseText); // Données textuelles récupérées
}
};
Le alert
c'est bien
beau, mais à part vérifier si la réception est bonne, ça ne sert à rien. Si on s'amuse à récupérer des
données, c'est pour les traiter ! Le traitement peut se faire directement dans la fonction anonyme définie
dans onreadystatechange
. Mais c'est très laid et ça n'a rien à
faire là, il vaut mieux séparer les codes pour avoir deux fonctions concises plutôt qu'une grosse.
On va donc définir ce qu'on appelle une fonction dite "de callback". Une fonction de callback est une fonction de rappel, exécutée généralement après qu'un script a été exécuté. C'est pas très clair, mais c'est tout con en fait : il s'agit de passer à une fonction A le nom d'une fonction B qui sera lancée une fois que la fonction A aura été exécutée. Comme ceci en gros :
function funcA(callback) {
// instruction...
// instruction...
// instruction...
callback();
}
function funcB() {
alert("Plop");
}
funcA(funcB);
En me basant sur cet exemple de callback, il est donc facile de le transposer pour utiliser XMLHttpRequest :
function request(callback) {
var xhr = getXMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && (xhr.status == 200 || xhr.status == 0)) {
callback(xhr.responseText);
}
};
xhr.open("GET", "handlingData.php", true);
xhr.send(null);
}
function readData(sData) {
// On peut maintenant traiter les données sans encombrer l'objet XHR.
if (sData == "OK") {
alert("C'est bon");
} else {
alert("Y'a eu un problème");
}
}
request(readData);
Illustrons ceci par deux exemples simples.
On va simplement lire le contenu d'un fichier XML, fichier que voici :
<?xml version="1.0" encoding="utf-8"?>
<!-- XMLHttpRequest_getXML.xml -->
name="Adobe Dreamweaver"
name="Microsoft Expression Web"
name="Notepad++"
name="gedit"
name="Emacs"
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
xmlns="http://www.w3.org/1999/xhtml"
http-equiv="Content-Type" content="text/html; charset=utf-8"
Techniques AJAX - XMLHttpRequest
type="text/javascript" src="oXHR.js"
type="text/javascript"
<!--
function request(callback) {
var xhr = getXMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && (xhr.status == 200 || xhr.status == 0)) {
callback(xhr.responseXML);
}
};
xhr.open("GET", "XMLHttpRequest_getXML.xml", true);
xhr.send(null);
}
function readData(oData) {
var nodes = oData.getElementsByTagName("soft");
var ol = document.createElement("ol"), li, cn;
for (var i=0, c=nodes.length; i<c; i++) {
li = document.createElement("li");
cn = document.createTextNode(nodes[i].getAttribute("name"));
li.appendChild(cn);
ol.appendChild(li);
}
document.getElementById("output").appendChild(ol);
}
//-->
onclick="request(readData);"Afficher le fichier XML
id="output"
En cliquant sur le bouton, on envoie la requête qui va se charger de récupérer les données, au format XML (avec responseXML donc). Ensuite, dans la fonction readData, on lit ces données et on crée une liste à puces que l'on va ajouter à l'élément appelé output.
Ici, on va demander à l'utilisateur d'entrer son pseudonyme ainsi que son prénom. Ces deux données seront transmises à une page PHP qui renverra un texte avec les données envoyées. Ça n'a aucun intérêt comme ça, mais c'est pour vous donner une base simple.
Voici la page HTML :
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
xmlns="http://www.w3.org/1999/xhtml"
http-equiv="Content-Type" content="text/html; charset=utf-8"
Techniques AJAX - XMLHttpRequest
type="text/javascript" src="oXHR.js"
type="text/javascript"
<!--
function request(callback) {
var xhr = getXMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && (xhr.status == 200 || xhr.status == 0)) {
callback(xhr.responseText);
}
};
var nick = encodeURIComponent(document.getElementById("nick").value);
var name = encodeURIComponent(document.getElementById("name").value);
xhr.open("GET", "XMLHttpRequest_getString.php?Nick=" + nick + "&Name=" + name, true);
xhr.send(null);
}
function readData(sData) {
alert(sData);
}
//-->
for="nick"Pseudo :
type="text" id="nick"
for="name"Prénom :
type="text" id="name"
type="button" onclick="request(readData);" value="Exécuter"
Et la page de script PHP qui va traiter la requête et renvoyer la petite phrase :
<?php
header("Content-Type: text/plain");
$nick = (isset($_GET["Nick"])) ? $_GET["Nick"] : NULL;
$name = (isset($_GET["Name"])) ? $_GET["Name"] : NULL;
if ($nick && $name) {
echo "Bonjour " . $name . " ! Je vois que votre pseudo est " . $nick;
} else {
echo "FAIL";
}
?>
Notez bien l'utilisation d'encodeURIComponent pour protéger les
données transmises. Si tout se passe bien, un alert
s'affichera avec la petite phrase renvoyée par le script PHP.
Grâce à readyState, on sait connaitre l'état de la requête. Il peut donc être intéressant de dire à l'internaute que la requête est en train d'être traitée et affichant un petit texte "Chargement en cours" ou bien une petite image de progression.
Si quand readyState vaut 4 tout est terminé, ça veut donc dire que si ça ne vaut pas 4, c'est en cours de traitement. De là, il n'y a qu'un pas pour afficher une image de progression comme on va le voir dans cet exemple :
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
xmlns="http://www.w3.org/1999/xhtml"
http-equiv="Content-Type" content="text/html; charset=utf-8"
Techniques AJAX - XMLHttpRequest
type="text/javascript" src="oXHR.js"
type="text/javascript"
<!--
function request(callback) {
var sleep = document.getElementById("sleep").value;
if (isNaN(parseInt(sleep))) {
alert(sleep + " n'est pas un nombre valide !");
return;
}
var xhr = getXMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && (xhr.status == 200 || xhr.status == 0)) {
callback(xhr.responseText);
document.getElementById("loader").style.display = "none";
} else if (xhr.readyState < 4) {
document.getElementById("loader").style.display = "inline";
}
};
xhr.open("GET", "XMLHttpRequest_getSleep.php?Sleep=" + sleep, true);
xhr.send(null);
}
function readData(sData) {
alert(sData);
}
//-->
for="sleep"Temps de sommeil :
type="text" id="sleep"
type="button" onclick="request(readData);" value="Exécuter"
id="loader" style="display: none;" src="loader.gif" alt="loading"
Il s'agit simplement d'afficher l'image de progression contenue
dans le span
loader. Pour être sur de bien le voir
(car une simple requête comme ça prend moins d'une seconde), j'utilise une fonction sleep dans la page XMLHttpRequest_getSleep.php,
page que voici :
<?php
header("Content-Type: text/plain");
$sleep = (isset($_GET["Sleep"])) ? $_GET["Sleep"] : NULL;
echo date("h:i:s") . "\n\n";
if ($sleep) {
sleep($sleep);
echo $sleep . "\n\n";
} else {
sleep(10);
echo "10\n\n";
}
echo date("h:i:s") . "\n";
?>
En considérant l'exemple précédent, que se passe-t-il si l'utilisateur clique plusieurs fois sur le bouton d'envoi ? Et bien la réponse est simple, la requête est envoyée plusieurs fois. Ce qu'il faudrait c'est trouver une astuce pour annuler la requête en cours si une nouvelle est envoyée.
Pour ce fait, il va falloir stocker l'objet XMLHttpRequest dans un objet global, xhr, et il n'y aura qu'à tester l'état de cet objet avant d'envoyer une nouvelle requête. Si l'état est différent de 0 (la requête est en cours), il suffit de l'annuler pour envoyer la nouvelle. On peut aussi décider de ne pas envoyer la nouvelle, au choix ça.
var xhr = null;
function request(callback) {
if (xhr && xhr.readyState != 0) {
xhr.abort(); // On annule la requête en cours !
}
xhr = getXMLHttpRequest(); // plus de mot clé 'var'
xhr.onreadystatechange = function() {
/* ... */
};
xhr.open("GET", "XMLHttpRequest_getSleep.php?Sleep=" + sleep, true);
xhr.send(null);
}
var xhr = null;
function request(callback) {
if (xhr && xhr.readyState != 0) {
alert("Attendez que la requête ait abouti avant de faire joujou");
return;
}
xhr = getXMLHttpRequest();
/* ... */
}
Les listes liées c'est quelque chose d'assez habituel : une première liste déroulante permet de choisir une option, et en fonction de ce choix, on affiche le contenu d'une deuxième liste. C'est assez simple et c'est un bon exercice.
Une première liste déroulante est affichée, proposant à l'utilisateur de choisir un éditeur de logiciels (c'est pour l'exemple). Quand l'utilisateur choisit un éditeur, on récupère, via XHR, la liste des logiciels qui correspondent à cet éditeur, et on l'affiche dans une deuxième liste déroulante.
La liste des éditeurs et des logiciels est enregistrée dans une base de données. Dans mon exemple, j'utilise une base mySQL. Voici d'ailleurs les requêtes SQL pour créer les deux tables que je vais utiliser :
CREATE TABLE IF NOT EXISTS `ajax_example_editors` (
`id` tinyint(4) NOT NULL AUTO_INCREMENT,
`name` varchar(50) collate latin1_general_ci NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci AUTO_INCREMENT=7 ;
INSERT INTO `ajax_example_editors` (`id`, `name`) VALUES
(1, 'Adobe'),
(2, 'Macromedia'),
(3, 'Microsoft'),
(4, 'Mozilla'),
(5, 'ACDSystem'),
(6, 'Apple');
CREATE TABLE IF NOT EXISTS `ajax_example_softwares` (
`id` tinyint(4) NOT NULL AUTO_INCREMENT,
`name` varchar(50) collate latin1_general_ci NOT NULL,
`idEditor` tinyint(4) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci AUTO_INCREMENT=21 ;
INSERT INTO `ajax_example_softwares` (`id`, `name`, `idEditor`) VALUES
(1, 'Photoshop', 1),
(2, 'GoLive', 1),
(3, 'InDesign', 1),
(4, 'Acrobat', 1),
(5, 'Dreamweaver', 2),
(6, 'Flash', 2),
(7, 'ColdFusion', 2),
(8, 'FlashPaper', 2),
(9, 'Silverlight', 3),
(10, 'Internet Explorer', 3),
(11, 'Office', 3),
(12, 'Visual Studio', 3),
(13, 'Camino', 4),
(14, 'Firefox', 4),
(15, 'Rhino', 4),
(16, 'Thunderbird', 4),
(17, 'ACDSee Photo Editor', 5),
(18, 'ACDSee Photo Manager', 5),
(19, 'iTunes', 6),
(20, 'Safari for Windows', 6);
En réalité, ce sera une page PHP, car je vais utiliser un script PHP pour afficher la liste des éditeurs dans la liste déroulante :
id="programBox"
id="editors"
id="editorsSelect" onchange="request(this);"
value="none"Selection
<?php
mysql_connect($hote, $login, $m_d_p);
mysql_select_db($bdd);
$query = mysql_query("SELECT * FROM ajax_example_editors ORDER BY name");
while ($back = mysql_fetch_assoc($query)) {
echo "\t\t\t\t<option value=\"" . $back["id"] . "\">" . $back["name"] . "</option>\n";
}
?>
id="loader" style="display: none;" src="images/loader.gif" alt="loading"
id="softwares"
id="softwaresSelect"
Du côté du code JavaScript pour envoyer la requête, c'est assez simple. Voici la fonction request, appelée via l'évènement onchange de l'élément <select>. Cette fonction se charge d'envoyer la requête.
function request(oSelect) {
var value = oSelect.options[oSelect.selectedIndex].value;
var xhr = getXMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && (xhr.status == 200 || xhr.status == 0)) {
readData(xhr.responseXML);
document.getElementById("loader").style.display = "none";
} else if (xhr.readyState < 4) {
document.getElementById("loader").style.display = "inline";
}
};
xhr.open("POST", "XMLHttpRequest_getListData.php", true);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.send("IdEditor=" + value);
}
La fonction readData sera appelée et se chargera de remplir le <select> avec la liste des logiciels. J'en reparlerai après le code PHP.
<?php
header("Content-Type: text/xml");
echo "<?xml version=\"1.0\" encoding=\"utf-8\"?>";
echo "<list>";
$idEditor = (isset($_POST["IdEditor"])) ? htmlentities($_POST["IdEditor"]) : NULL;
if ($idEditor) {
mysql_connect($hote, $login, $m_d_p);
mysql_select_db($bdd);
$query = mysql_query("SELECT * FROM ajax_example_softwares WHERE idEditor=" . mysql_real_escape_string($idEditor) . " ORDER BY name");
while ($back = mysql_fetch_assoc($query)) {
echo "<item id=\"" . $back["id"] . "\" name=\"" . $back["name"] . "\" />";
}
}
echo "</list>";
?>
C'est une simple récupération de base de données avec PHP. Il faut juste bien penser à formater comme étant du XML :
<?php
header("Content-Type: text/xml");
?>
Et s'arranger pour produire une structure XML valide !
Le code XML généré sera sous cette forme :
<?xml version="1.0" encoding="utf-8"?>
id="0" name="Programme A"
id="1" name="programme B"
...
Voici donc la fonction readData qui analyse les données XML et recrée les éléments <option> de la liste déroulante :
function readData(oData) {
var nodes = oData.getElementsByTagName("item");
var oSelect = document.getElementById("softwaresSelect");
var oOption, oInner;
oSelect.innerHTML = "";
for (var i=0, c=nodes.length; i<c; i++) {
oOption = document.createElement("option");
oInner = document.createTextNode(nodes[i].getAttribute("name"));
oOption.value = nodes[i].getAttribute("id");
oOption.appendChild(oInner);
oSelect.appendChild(oOption);
}
}
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
xmlns="http://www.w3.org/1999/xhtml"
http-equiv="Content-Type" content="text/html; charset=utf-8"
Techniques AJAX - XMLHttpRequest
type="text/javascript" src="oXHR.js"
type="text/javascript"
<!--
function request(oSelect) {
var value = oSelect.options[oSelect.selectedIndex].value;
var xhr = getXMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && (xhr.status == 200 || xhr.status == 0)) {
readData(xhr.responseXML);
document.getElementById("loader").style.display = "none";
} else if (xhr.readyState < 4) {
document.getElementById("loader").style.display = "inline";
}
};
xhr.open("POST", "XMLHttpRequest_getListData.php", true);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.send("IdEditor=" + value);
}
function readData(oData) {
var nodes = oData.getElementsByTagName("item");
var oSelect = document.getElementById("softwaresSelect");
var oOption, oInner;
oSelect.innerHTML = "";
for (var i=0, c=nodes.length; i<c; i++) {
oOption = document.createElement("option");
oInner = document.createTextNode(nodes[i].getAttribute("name"));
oOption.value = nodes[i].getAttribute("id");
oOption.appendChild(oInner);
oSelect.appendChild(oOption);
}
}
//-->
Programmes
id="programBox"
id="editors"
id="editorsSelect" onchange="request(this);"
value="none"Selection
<?php
mysql_connect($hote, $login, $m_d_p);
mysql_select_db($bdd);
$query = mysql_query("SELECT * FROM ajax_example_editors ORDER BY name");
while ($back = mysql_fetch_assoc($query)) {
echo "\t\t\t\t<option value=\"" . $back["id"] . "\">" . $back["name"] . "</option>\n";
}
?>
id="loader" style="display: none;" src="images/loader.gif" alt="loading"
id="softwares"
id="softwaresSelect"
Pour terminer, voici une vue globale des propriétés et méthodes qui s'appliquent à l'objet XMLHttpRequest.
Disponibilité |
Description |
|
---|---|---|
onreadystatechange |
Tous |
Propriété exécutée à chaque changement d'état de la requête |
readyState |
Tous |
Etat de la requête, à vérifier au sein du onreadystatechange pour savoir où en est le traitement de la requête |
responseText |
Tous |
Réponse du serveur, au format texte |
responseXML |
Tous |
Réponse du serveur, au format XML |
status |
Tous |
Code de réponse du serveur (200, 404, 500...) |
statusText |
Tous |
Le message associé à status |
timeout |
IE8, non-W3C |
Permet de définir un time-out |
Disponibilité |
Description |
|
---|---|---|
abort |
Tous |
Annule la requête en cours d'exécution |
getAllResponseHeaders |
Tous - IE7 |
Récupère la liste complète des en-têtes de la requête |
getResponseHeader |
Tous - IE7 |
Récupère l'en-tête de la requête |
open |
Tous |
Définit les modalités d'envoi de la requête |
overrideMimeType |
Tous sauf IE, non-W3C |
Permet de forcer le type MIME de la requête |
send |
Tous |
Envoie la requête |
setRequestHeader |
Tous |
Ajoute un en-tête HTTP manuellement |
XMLHttpRequest est sans conteste le système AJAX qui offre le plus de marge de manœuvre, mais il se révèle lourd à déployer.
Adapté pour envoyer une requête qui n'attend pas nécessairement de résultat
Adapté pour récupérer des données textuelles et XML
Supporté par tous les navigateurs
Possibilité de requêtes POST
Assez lourd à mettre en place et à manipuler
L'importation de données au format JSON requiert une compilation avec eval