Une fonction ajax simple, compatible et prête à l’emploi
L’ajax (Asynchronous Javascript And Xml), c’est bien ! Cette technologie permet d’alléger le trafic web et d’accroître l’ergonomie et l’expérience utilisateur.
Pourtant, le concept de transfert asynchrone n’est pas simple à aborder et les tutoriels sur le sujet sont parfois très longs.
Voici une fonction ajax prête à l’emploi, simple à utiliser, compatible avec tous les navigateurs et indépendante (aucune librairie javascript n’est requise).
Un peu d’histoire
Cette fonction a été initialement créée par Sutekidane en 2005 : l’article et la fonction brute d’époque.
Les fonctions (en réalité il y en a deux : XHRConnection et chargeFichier) ont été modifiées principalement pour permettre l’appel d’une fonction après le chargement de l’ajax (un callback), si ce dernier a réussi.
D’autres bugs mineurs ont été corrigés (comme l’erreur lors d’une requête de type POST).
Fonctions et documentation
Voici les deux fonctions, à placer dans un fichier JS ou dans une balise <script> [téléchargement direct] :
function XHRConnection()
{
// + ----------------------------------------------------------------------------------
var conn = false;
var debug = true;
var datas = new String();
var areaId = new String();
// Objet XML
var xmlObj;
// Type de comportement au chargement du XML
var xmlLoad;
// + ----------------------------------------------------------------------------------
try {
conn = new XMLHttpRequest();
}
catch (error) {
if (debug) { alert('Erreur lors de la tentative de création de l\'objet \nnew XMLHttpRequest()\n\n' + error); }
try {
conn = new ActiveXObject("Microsoft.XMLHTTP");
}
catch (error) {
if (debug) { alert('Erreur lors de la tentative de création de l\'objet \nnew ActiveXObject("Microsoft.XMLHTTP")\n\n' + error); }
try {
conn = new ActiveXObject("Msxml2.XMLHTTP");
}
catch (error) {
if (debug) { alert('Erreur lors de la tentative de création de l\'objet \nnew ActiveXObject("Msxml2.XMLHTTP")\n\n' + error); }
conn = false;
}
}
}
// + ----------------------------------------------------------------------------------
// + setDebugOff
// + Désactive l'affichage des exceptions
// + ----------------------------------------------------------------------------------
this.setDebugOff = function() {
debug = false;
};
// + ----------------------------------------------------------------------------------
// + setDebugOn
// + Active l'affichage des exceptions
// + ----------------------------------------------------------------------------------
this.setDebugOn = function() {
debug = true;
};
// + ----------------------------------------------------------------------------------
// + resetData
// + Permet de vider la pile des données
// + ----------------------------------------------------------------------------------
this.resetData = function() {
datas = new String();
datas = '';
};
// + ----------------------------------------------------------------------------------
// + appendData
// + Permet d'empiler des données afin de les envoyer
// + ----------------------------------------------------------------------------------
this.appendData = function(pfield, pvalue) {
datas += (datas.length == 0) ? pfield+ "=" + escape(pvalue) : "&" + pfield + "=" + escape(pvalue);
};
// + ----------------------------------------------------------------------------------
// + setRefreshArea
// + Indique quel elment identifié par id est valoris lorsque l'objet XHR reoit une réponse
// + ----------------------------------------------------------------------------------
this.setRefreshArea = function(id) {
areaId = id;
};
// + ----------------------------------------------------------------------------------
// + createXMLObject
// + Méthode permettant de créer un objet DOM, retourne la réfrence
// + Inspiré de: http://www.quirksmode.org/dom/importxml.html
// + ----------------------------------------------------------------------------------
this.createXMLObject = function() {
try {
xmlDoc = document.implementation.createDocument("", "", null);
xmlLoad = 'onload';
}
catch (error) {
try {
xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
xmlLoad = 'onreadystatechange ';
}
catch (error) {
if (debug) { alert('Erreur lors de la tentative de création de l\'objet XML\n\n'); }
return false;
}
}
return xmlDoc;
}
// + ----------------------------------------------------------------------------------
// + Permet de définir l'objet XML qui doit être valorisé lorsque l'objet XHR reoit une réponse
// + ----------------------------------------------------------------------------------
this.setXMLObject = function(obj) {
if (obj == undefined) {
if (debug) { alert('Paramètre manquant lors de l\'appel de la méthode setXMLObject'); }
return false;
}
try {
//xmlObj = this.createXMLObject();
xmlObj = obj;
}
catch (error) {
if (debug) { alert('Erreur lors de l\'affectation de l\'objet XML dans la méthode setXMLObject'); }
}
}
// + ----------------------------------------------------------------------------------
// + loadXML
// + Charge un fichier XML
// + Entrées
// + xml String Le fichier XML à charger
// + ----------------------------------------------------------------------------------
this.loadXML = function(xml, callBack) {
if (!conn) return false;
// Chargement pour alimenter un objet DOM
if (xmlObj && xml) {
if (typeof callBack == "function") {
if (xmlLoad == 'onload') {
xmlObj.onload = function() {
callBack(xmlObj);
}
}
else {
xmlObj.onreadystatechange = function() {
if (xmlObj.readyState == 4) callBack(xmlObj)
}
}
}
xmlObj.load(xml);
return;
}
}
// + ----------------------------------------------------------------------------------
// + sendAndLoad
// + Connexion à la page désirée avec envoie des données, puis mise en attente de la réponse
// + Entrées
// + Url String L'url de la page à laquelle l'objet doit se connecter
// + httpMode String La méthode de communication HTTP : GET, HEAD ou POST
// + callBack Objet Le nom de la fonction de callback
// + ----------------------------------------------------------------------------------
this.sendAndLoad = function(Url, httpMode, callBack) {
httpMode = httpMode.toUpperCase();
conn.onreadystatechange = function() {
if (conn.readyState == 4 && conn.status == 200) {
// Si une fonction de callBack a été définie
// Si une zone destinée à récupérer le résultat a été définie
if (areaId.length > 0){
try {
document.getElementById(areaId).innerHTML = conn.responseText;
}
catch(error) {
if (debug) { alert('Echec, ' + areaId + ' n\'est pas un objet valide'); }
return false;
}
if (typeof callBack == "function") {
callBack();
}
return;
}
}
};
switch(httpMode) {
case "GET":
try {
Url = (datas.length > 0) ? Url + "?" + datas : Url;
conn.open("GET", Url);
conn.send(null);
}
catch(error) {
if (debug) { alert('Echec lors de la transaction avec ' + Url + ' via la méthode GET'); }
return false;
}
break;
case "POST":
try {
tab_url = Url.split('?');
nom_fichier = tab_url[0];
datas = tab_url[1];
conn.open("POST", nom_fichier);
conn.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
conn.send(datas);
}
catch(error) {
if (debug) { alert('Echec lors de la transaction avec ' + Url + ' via la mthode POST'); }
return false;
}
break;
default :
return false;
break;
}
return true;
};
return this;
}
function chargeFichier(fichier, zone, methode, callback)
{
if (methode == undefined) { methode = "GET"; }
if (callback == undefined) { callback = "void()"; }
callback = new Function("callback", callback + ";");
var XHR = new XHRConnection();
XHR.setRefreshArea(zone);
XHR.sendAndLoad(fichier + "&time=" + new Date().getTime(), methode, callback );
return true;
}
La fonction XHRConnection permet de créer l’objet XML en fonction du navigateur. De votre côté vous utiliserez chargeFichier ainsi :
chargeFichier(fichier, zone, methode, callback);
Voici comment utiliser les paramètres :
- Fichier : fichier à charger et ses paramètres, par exemple : page2.php?id=3&login=xxx
- Zone : Identifiant (attribut id) de l’élément HTML à utiliser : un div, un td, un span…
- Méthode : GET ou POST au choix. La méthode GET sera soumise aux problèmes d’encodage des caractères dans les url.
- Callback : Une fonction JS à appeler à la fin du chargement ajax, si ce dernier à réussi, ce paramètre peut être vide.
Dans le cas d’une requête POST (recommandé), les paramètres doivent être renseignés comme pour une requête GET, sous la forme page.php?parametre=1&utilisateur=2.
Quelques exemples
Requête POST sur page2.php, appel de la fonction postajax() après chargement :
chargeFichier("page.php?parametre=valeur", "div_ajax", "POST", "postajax()");
Requête GET sur page2.php, sans fonction de callback :
chargeFichier("page2.php?parametre=valeur", "span_ajax", "GET", "");
N’hésitez pas à me donner vos retours quant à l’utilisation de la fonction.
Réalisé et rédigé avec Julien TAUBENHAUS dans le cadre de son projet SUPINFO.