Le fonctionnement habituel, lors de connexions client serveur, est d’utiliser un formulaire coté client et d’envoyer les valeurs au serveur. Celui-ci traitera les informations puis créera une nouvelle page qu’il enverra au client.
AJAX permet de masquer les transactions client serveur. Nous allons réaliser toutes les transactions en JavaScript et récupérer le résultat dans une variable. Cela nous permettra de traiter nous même le résultat renvoyé par le serveur. L’objectif est ensuite de modifier dans la page le strict nécessaire.
Cette article est à conseiller sur le fonctionnement d'AJAX.
JavaScript propose un certain nombre de types de variables. Ils sont indiqués par le type de la valeur assignée à la variable. Pour définir une variable, la syntaxe est :
var mavariable;
On peut également lui assigner une valeur :
var mavariable = "hello world";
On peut noter plusieurs types de données :
Boolean ;
Integer ;
Float ;
String ;
Pour les définir, rien de plus simple :
var mavar = true; var mavar = 156; var mavar = "Bonjour";
La gestion des types est seulement nécessaire dans des cas particuliers comme lors de comparaisons de valeurs. Il est alors possible de forcer le type d’une variable lorsque c’est nécessaire :
// Passer une chaîne de caractères en entier var unInt = parseInt("111"); // Passer un entier en chaîne de caractère var uneStr = 111 + "";
Le code javascript est généralement placé dans la partie <head> de la page ou dans un fichier séparé .js.
<html> <head> <title></title> <script type="text/javascript" src="/javascript/fonctions.js"></script> <script language="JavaScript"> // mon code Js var maVar; </script> </head> <body> </body> </html>
Pour pouvoir coder, il nous manque encore quelques petites choses. Tout d’abord, la syntaxe des fonctions :
function Nom_de_la_fonction (param1, param2) { // instructions; }
La syntaxe du for :
for (i = 1; i <= 10; i++){ ; }
La syntaxe du if :
if (condition) { ; } else { ; }
Les chaînes de caractères sont un type très utilisé. Voici donc quelques fonctions très pratiques :
Longueur de la chaîne de caractère : variable.length.
Mettre une chaîne en majuscule : variable.toUpperCase().
Mettre une chaîne en minuscule : variable.toLowerCase().
Concaténation de chaîne : "cours" + "_" + "eof" donne "cours_eof".
Récupérer une partie d’une chaîne : variable.substr(1 , 2) retourne pour variable = "toto" : "ot". Le premier paramètre est l’index du premier caractère que l’on choisit et le deuxième paramètre le nombre de caractère. Le premier caractère d’une chaîne a pour index : 0.
Il existe de nombreuses possibilités d’intéragir avec le document HTML directement en JavaScript. L’intérêt d’AJAX est de ne pas avoir à recharger la page, on va donc voir comment écrire simplement dans le document HTML. La solution simple est de donner un identifiant (un id) à un élément HTML, par exemple, <div id="message"> et d’utiliser la propriété innerHTML pour changer le contenu :
document.getElementById("message").innerHTML = "Message : "+ MonMessage;
Il est préférable de penser le document HTML comme un document XML. Il est alors possible de créer des noeuds et de les ajouter. On parle alors du Document Object Model.
Puisque le langage JavaScript permet de faire de l’objet, autant en profiter. Voici comment définir des objets :
// Définition d'un Objet. function MonObjet() { // Attributs this.monAttribut = ""; } // Définition d'une méthode. MonObjet.prototype.maMethode = function(param) { // Code de la méthode } // Création d’un Objet. var instanceDeMonObjet = new MonObjet(); /*! * Exemple */ function carre() { this.cote = 0; } carre.prototype.setCote = function(newCote) { this.cote = newCote; return this.cote; } carre.prototype.aire = function() { return this.cote * this.cote; } carre.prototype.perimetre = function() { return this.cote * 4; } var monCarre = new carre();
Nous allons maintenant voir les différents éléments de la connexion client serveur.
Coté serveur, nous utiliserons PHP. Nous allons appeler un script auquel nous passerons des informations en GET et il nous retournera l’utilisateur. Voici un script permettant de vérifier si le nom d’utilisateur est correct :
<?php $login = isset($_GET["loginToCheck"]) ? $_GET["loginToCheck"] : 0; $correctLogin = "arno"; if ($login == $correctLogin) return "ok"; return "Essayez encore"; ?>
Il n’y a donc aucune difficulté particulière du coté serveur.
Nous allons maintenant récupérer du texte en JavaScript. Pour ce faire nous allons utiliser trois fonctions :
Une pour définir l’url php à appeler et la méthode d’affichage.
Une pour appeler l’url php.
Une pour utiliser le résultat.
La première fonction sert donc à définir deux variables et enchainera toutes les tâches. C’est elle que nous utiliserons :
function getInfosToDisplay (param) { // send request mode url = "http://monsite/monscript.php?monparam=" + param; // Méthode affichant le résultat. methodToCall = "useTxtInfo"; // Appelle la méthode pour se connecter au serveur. loadXMLDoc(url, methodToCall); }
Voyons maintenant loadXMLDoc :
function loadXMLDoc (url, methodToCall) { // Pour les navigateurs non IE. if (window.XMLHttpRequest) { objReq= new XMLHttpRequest(); // methodToCall sera la fonction appelée lorsque la page php sera chargée. objReq.onreadystatechange = eval(methodToCall); objReq.open("GET", url, true); objReq.send(null); // Pour Internet Explorer ( activeX doit être activé). } else if (window.ActiveXObject) { objReq = new ActiveXObject("Microsoft.XMLHTTP"); if (objReq) { objReq.onreadystatechange = eval(methodToCall); objReq.open("GET", url, true); objReq.send(); } } }
Le fait de passer la méthode et le script php en paramètre nous permettra de réutiliser loadXMLDoc pour appeler des scripts php différents et des méthodes d’affichages différentes. loadXMLDoc sera donc facilement réutilisable.
Il ne nous reste plus qu’à afficher le résultat :
function useTxtInfo() { if (objReq.readyState == 4) { // 4 signifie que le chargement est "complet". if (objReq.status == 200) { // Le serveur web retourne ok (il aurait retournée 404 si le script n’existait pas, etc.). // On récupère le texte dans la variable serverAnswer. serverAnswer = objReq.responseText; // On affiche. document.getElementById("answer").innerHTML = serverAnswer; } else { alert("Problème :\n" + objReq.statusText); } } }
Et voila, il ne reste plus qu’à créer un div avec l’id "answer" dans la page html pour afficher la réponse.
Voici le codee utilisé (côté serveur) pour les besoins du test :
[adminbdd html]$ cat server.php
<?php // L'en-tête Access-Control-Allow-Origin sert à définir le domaine pour lequel les données pourront être renvoyées. header("Access-Control-Allow-Origin: *"); $login = isset($_GET["loginToCheck"]) ? $_GET["loginToCheck"] : 0; $correctLogin = "arno"; if ($login == $correctLogin) echo "ok"; else echo "Essayez encore"; ?>
Le code côté client :
<html> <head> <title></title> <script type="text/javascript">
function getInfosToDisplay (login) { // send request mode url = "http://192.168.5.53/server.php?loginToCheck=" + login; // Méthode affichant le résultat. methodToCall = "useTxtInfo"; // Appelle la méthode pour se connecter au serveur. loadXMLDoc(url, methodToCall); } function loadXMLDoc (url, methodToCall) { // Pour les navigateurs non IE. if (window.XMLHttpRequest) { objReq = new XMLHttpRequest(); // methodToCall sera la fonction appelée lorsque la page php sera chargée. objReq.onreadystatechange = eval(methodToCall); objReq.open("GET", url, true); objReq.send(); // Pour Internet Explorer ( activeX doit être activé). } else if (window.ActiveXObject) { objReq = new ActiveXObject("Microsoft.XMLHTTP"); if (objReq) { objReq.onreadystatechange = eval(methodToCall); objReq.open("GET", url, true); objReq.send(); } } } function useTxtInfo() { if (objReq.readyState == 4) { // 4 signifie que le chargement est "complet". if (objReq.status == 200) { // Le serveur web retourne ok (il aurait retournée 404 si le script n’existait pas, etc.). // On récupère le texte dans la variable serverAnswer. serverAnswer = objReq.responseText; // On affiche. document.getElementById("answer").innerHTML = serverAnswer; } else { alert("Problème :\n" + objReq.statusText); } } }
</script> </head> <body> <input type="text" onKeyUp="javascript:getInfosToDisplay(this.value)" /> <div id="answer"></div> </body> </html>
Cette solution est simple et permet de récupérer du texte, ou du code HTML formaté, mais elle est peu pratique pour des données.
Par exemple, dans le cas d’un agenda collaboratif, il n’est pas possible de récupérer les événements.
Lorsque l’on souhaite récupérer des données pour les traiter en JavaScript (les dates de début et de fin des évènements pour l’agenda), on peut utiliser du XML. Le PHP nous renvoie alors un document XML que l’on récupère. La différence sera juste dans useTxtInfo, d’où l’intérêt de découper.
Voici un exemple de la syntaxe à utiliser.
Flux XML :
<lststudent> <student> <id>1</id> <name>Arnauld</name> </student> <student> <id>2</id> <name>Johan</name> </student> <student> <id>3</id> <name>Denis</name> </student> </lststudent>
Code JavaScript :
function useXmlInfoForStudent() { if (objReqStudent.readyState == 4) { // status is complete if (objReqStudent.status == 200) { // webserver return ok // on récupère du XML serverAnswer = objReqStudent.responseXML; var lststudent = serverAnswer.getElementsByTagName('lststudent'); for (i = 0 ; i < lststudent[0].childNodes.length ; i++) { //for each student of lstStudent //display all the student for (j = 0 ; j < lstday[0].childNodes[i].childNodes.length ; j++) { //for each node of studeny if (lstday[0].childNodes[i].childNodes[j].childNodes[l].nodeType != 1) //on test si le noeud contient quelque chose continue; // s’il est vide on passe au suivant //on récupère le nom du node curNodeName = lstday[0].childNodes[i].childNodes[j].nodeName; switch (curNodeName) { case "id": // on récupère l’id buffId = lstday[0].childNodes[i].childNodes[j].childNodes[l].firstChild.nodeValue; break; case "name": // on récupère le nom buffName = lstday[0].childNodes[i].childNodes[j].childNodes[l].firstChild.nodeValue; break; } } // on a un nouvel étudiant, traitement de l’étudiant ici document.getElementById("listeEtudiant").innerHTML += "<br />id : " + buffId document.getElementById("listeEtudiant").innerHTML += " | nom : " + buffName; } } } }
Comme vous le voyez, le XML est un peu plus difficile à traiter mais il offre énormément de souplesse.