Utilisation de l'objet XMLHttpRequest

Décembre 2016


Utilisation de l'objet XMLHttpRequest





I - Introduction


1.1 - Quelques mots


De plus en plus de sites web dynamiques (faisant appel à une base de données par exemple) requièrent une mise à jour de ses différentes pages, ou une partie de ses pages, de manière transparente, sans que l’utilisateur n’ait à rafraîchir lui-même la page.

C’est ce que l’on appel communément la méthode Ajax. Cette méthodologie se retrouve sous plusieurs techniques, notamment l’utilisation des objets XMLHttpRequest de Javascript.

Nous allons donc voir au travers de cette astuce, ce qu’est l’objet XHR, et comment l’implémenter dans nos codes de manière simple.

1.2 - Techniques pré-requises


Afin de comprendre parfaitement les explications de cette astuce, il est préférable de maitriser les sujets qui suivent :

II - Présentation


2.1 - Principe


L’utilisation de XHR est relativement simple en soit. Il vous suffit d’instancier un objet de ce type, d’ouvrir une url (ou un fichier local à votre serveur si vous préférez) et d’envoyer une requête (de type GET ou POST) avec ou sans paramètres.
Malgré le fait que l’objet XHR puisse être utilisé avec plusieurs types de protocole, nous ne nous intéresserons à son utilisation qu’au travers du protocole HTTP.
Le code d’état HTTP de la requête (réponse) ainsi que les données (le document) qui lui sont rattachés seront disponibles via cette instance d’objet.

2.2 - Utilisation asynchrone


L’objet XHR dispose d’une méthode d’appel et de retour, ce qui permet au navigateur de continuer à fonctionner normalement jusqu’à ce que la requête envoyée aboutisse et soit traitée en retour.

Dès lors, XHR peut s'utiliser pour plusieurs choses :
  • Mettre à jour des données dans une base de données
  • Récupérer des données d'une base de données
  • Rafraîchir la page courante dans le navigateur, par des données issues d'une base de données ou d'une session.

2.3 - Avantages

  • Diminution de la bande passante : comparé à un rafraîchissement ou l'exécution d'une page, ici seules les données sont envoyées, et non le document en entier.
  • Meilleure interactivité du site : en effet, les contrôles, mises à jour ou rafraîchissement des pages effectués par cette technologie se feront de manière transparente et sans action (plus ou moins) de la part de l'utilisateur.

2.4 - Inconvénients

  • Ne fonctionnera pas sans javascript. Or les utilisateurs peuvent bloquer les contrôles javascript de leur navigateur.
  • Nombre d'utilisation simultanée limitée : le nombre d'utilisations simultanées des requêtes XHR est configurée à 2 par défaut. Cela peut poser problème dans le cas où un utilisateur ouvre deux ou plusieurs onglets sur des sites utilisant cette technologie, provoquant un blocage du navigateur. Les fenêtres / onglets ouvert de la sorte ne seront alors plus redessinés, les contrôles fait par l'intermédiaire de XHR seront également bloqués.

III - Architecture


Afin de vous représenter au mieux ce qu'il se passe lors de l'utilisation d'un objet XHR, voici un schéma comparatif entre la méthode XHR et la méthode basique pour la soumission d'un formulaire HTML.
La partie haute du schéma décrivant l'utilisation de XHR, la partie basse étant la soumission normale d'un formulaire.



Globalement, on s'aperçoit que le chemin d'exécution est le même, aux différences suivantes :
  • XHR se fait de manière asynchrone
  • XHR retourne de la donnée XML qui peut alors être interprétée ou affichée dans le navigateur, alors que la soumission normale retourne une nouvelle page web à afficher dans le navigateur.

IV - Mise en pratique


La démarche suivante vise à simplifier votre utilisation de l'objet XHR au sein de vos pages web. Ceci toujours dans les buts listés ici

4.1 - Implémentation de la fonction générique 'callScript'


4.1.1 - Code 1


function callScript ( scriptName, args ){
	
	var xhr_object = null; 
	     
	// ### Construction de l’objet XMLHttpRequest selon le type de navigateur
	if(window.XMLHttpRequest) 
	   	xhr_object = new XMLHttpRequest(); 
	else if(window.ActiveXObject)
	  	 xhr_object = new ActiveXObject("Microsoft.XMLHTTP");
	else { 
                // XMLHttpRequest non supporté par le navigateur 
	   	alert("Votre navigateur ne supporte pas les objets XMLHTTPRequest..."); 
    		 return; 
	} 
	 
	xhr_object.open("POST", scriptName, true);
	
	//  Définition du comportement à adopter sur le changement d’état de l’objet XMLHttpRequest
	xhr_object.onreadystatechange = function() { 
	  	 if(xhr_object.readyState == 4) {
			//alert(xhr_object.responseText); // DEBUG MODE
			//document.write(xhr_object.responseText);
			eval(xhr_object.responseText);
		 }
		return xhr_object.readyState;
	} 
	xhr_object.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
	
	//  Envoi de la requête
	xhr_object.send(args);

}

4.1.2 - Explications code 1


La fonction 'callScript' a pour but d'être au maximum générique.
Les paramètres
  • scriptName : chemin d'accès au script de traitement que vous souhaitez appeler
  • args : liste des paramètres passés au script au format STRING. La syntaxe de cette liste sera toujours de la forme suivante: param_name1=param_val1&param_name2=param_val2&...

Instanciation de l'objet XHR
  • pour les navigateurs de type Netscape & co:

if(window.XMLHttpRequest) 
      xhr_object = new XMLHttpRequest(); 
  • pour les navigateur de type Internet Explorer:

else if(window.ActiveXObject)
      xhr_object = new ActiveXObject("Microsoft.XMLHTTP");

Ouverture de l'url / du script

xhr_object.open("POST", scriptName, true);

Définition du comportement à adopter en cas de changement d'état de la requête

xhr_object.onreadystatechange = function() { 
	if(xhr_object.readyState == 4) {
	        //alert(xhr_object.responseText); // DEBUG MODE
		//document.write(xhr_object.responseText);
		eval(xhr_object.responseText);
	}
	return xhr_object.readyState;
} 


La fonction 'onreadystatechange' sera la fonction appelée à chaque changement d'état de la requête envoyée. Il est donc important de lui redéfinir un nouveau comportement.
Pour ce faire, nous lui donnons de nouvelles instructions.
'xhr_object.readyState' permet de récupérer le statut de la requête. Dans le cas présent, la valeur 4 représente l'état 'Terminée'. Donc, lorsque la requête est terminée, nous lui indiquons d'interpréter la réponse comme s'il s'agissait de code javascript via l'instruction 'eval' sur l'élément 'xhr_object_responseText'.

Vous pouvez utiliser la réponse XML comme bon vous semble bien entendu. Dans le cas de cette astuce, le but principal étant de modifier le contenu d'une page web en retour de la réponse, la réponse est interprétée en pseudo code Javascript.
Définition du header de la requête

Une étape obligatoire
xhr_object.setRequestHeader("Content-type", "application/x-www-form-urlencoded");

Envoi de la requête

xhr_object.send(args);

4.2 - Exemple concret


Pour finaliser l'apprentissage de l'utilisation de l'objet XHR, nous allons mettre en place un formulaire simple, avec deux champs 'nom' et 'prénom', ainsi qu'un bouton pour activer une requête XHR qui appelera un script PHP donc le but sera de retourner du code Javascript pour afficher à l'écran les valeurs que vous aurez entrés dans les deux champs.
La mise en place de cet exemple passera par l'écriture de 3 fichiers:
  • 1 fichier Javascript, nommé 'fonction.js'
  • 1 fichier PHP avec formulaire, nommé 'index.php'
  • 1 fichier de traitement PHP, nommé 'traitement.php'

4.2.1 - Le formulaire HTML


Commencez donc par créer un fichier 'index.php' dans lequel vous copierez ce code :
<?php
include "fonctions.js";
?>

<BR>
Nom : <input type='text' id='nom' value=''/>
<BR>
Prénom : <input type='text' id='prenom' value=''/>
<BR>
<input type='button' value='Executer' onclick='executeSample()'/>
<BR>


Ce code est relativement simple, point besoin d'explications.
On notera l'appel de la fonction javascript 'executeSample' dont le code se trouve juste au dessous

4.2.2 - Les fonctions javascript


Au même endroit que le fichier créé précédemment, vous devrez en ajouter un nouveau qui répertoriera les fonctions Javascript utilisées par le formulaire HTML. Le fichier s'appellera 'fonctions.js'. Voici le code:
<script language="javascript">

function callScript ( scriptName, args ){
	
	var xhr_object = null; 
	     
	// ### Construction de l’objet XMLHttpRequest selon le type de navigateur
	// Cas des navigateurs de type Netscape (Firefore, Conqueror, etc.)
	if(window.XMLHttpRequest) 
	   	xhr_object = new XMLHttpRequest(); 
	// Cas du navigateur Internet Explorer
	else if(window.ActiveXObject)
	  	 xhr_object = new ActiveXObject("Microsoft.XMLHTTP");
	// Cas des navigateurs ne comprenant pas cette technologie (anciens navigateurs)
	else { 
			// XMLHttpRequest non supporté par le navigateur 
	 		alert("Votre navigateur ne supporte pas les objets XMLHTTPRequest..."); 
    	return; 
	} 
	 
	xhr_object.open("POST", scriptName, true);
	
	//  Définition du comportement à adopter sur le changement d’état de l’objet 
	// XMLHttpRequest
	xhr_object.onreadystatechange = function() { 
			// Etat : requête terminée, réponse récupérée
	  	if(xhr_object.readyState == 4) {
				//alert(xhr_object.responseText); // DEBUG MODE
				// ### Interprétation du retour du script appellé
				// Mode d’interprétation 1: on affiche dans la page le retour
				// comme s’il s’agissait de code HTML 
				//document.write(xhr_object.responseText);
				// Mode d’interprétation 2: on interprète le retour comme 
				// s’il s’agissait de code javascript
				eval(xhr_object.responseText);
		 	}
			return xhr_object.readyState;
	} 
	xhr_object.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
	
	//  Envoi de la requête
	xhr_object.send(args);

}

function executeSample (){
	// --- Récupération des paramètres nécessaire au script PHP
	var _nom = document.getElementById("nom").value;
	var _prenom = document.getElementById("prenom").value;
	
	var _data = "nom="+_nom+"&prenom="+_prenom;
	// --- Appel au script PHP de traitement
	callScript("traitement.php",_data);
}

</script>


Le code de la fonction 'callScript' est le même que précédemment.

La fonction 'executeSample' est chargée de récupérer la valeur des deux champs du formulaire afin de les passer à la fonction 'callScript' en tant que paramètre du script 'traitement.php'.

4.2.3 - Le script PHP de traitement


Enfin, toujours au même endroit que les précédents fichiers, vous devez créer le fichier 'traitement.php' avec le code suivant:
<?php
// --- Récupération des paramètres POST
if ( isset($_POST["nom"]) && !empty($_POST["nom"]) )
	$nom = $_POST["nom"];
else
	$nom = null;
	
if ( isset($_POST["prenom"]) && !empty($_POST["prenom"]) )
	$prenom = $_POST["prenom"];
else
	$prenom = null;

// --- Exécution du traitement
if ( $nom != null && $prenom != null ){
	// --- Le taitement consiste à retourner un code javascript qui sera interpréter au retour de
	// --- l'appel de ce script PHP.
	// --- Le code javascript ici affiche simplement les paramètres envoyés dans une pop-up
	echo "alert('Nom=".$nom." ,Prenom=".$prenom."');";
}

?>


Rien de mirobolant dans ce code. Le plus important réside dans la récupération des paramètres passés au script, et à l'envoi sur la sortie standard du script du résultat qui sera interprété dans l'objet XHR (lorsque la requête sera au statut 'Terminée')
Dans cet exemple, nous affichons donc les valeurs de 'nom' et 'prénom' rentrées par l'utilisateur.

La donnée XML retournée par le script, et donc réceptionnée dans l'objet XHR, sera :

alert('Nom=quelquechose ,Prenom=quelquechose');

Cette donnée XML sera alors interprété comme du Javascript (puisque c'est du code javascript, c'est tout là l'intérêt)

Dans ce script de traitement, vous pouvez tout aussi bien :
  • Mettre à jour des données dans une base de données
  • Récupérer des données depuis une base de données

Puis par la suite, mettre à jour la page web.

Exemple, si vous ajoutez dans le code du fichier 'index.php', une zone comme suit :
<div id='resultat'></div>


L'instruction du script de traitement pourrait alors être :
if ( $nom != null && $prenom != null ){
        echo "var oDiv = document.getElementById('resultat');";
	echo "oDiv.innerHTML = 'Nom: ".$nom."  - Prenom: ".$prenom."'";
}



Le résultat sera alors la mise à jour du contenu de la DIV 'resultat' dans la page web de départ, ceci automatiquement lors du clic sur le bouton du formulaire.

A voir également :

Ce document intitulé «  Utilisation de l'objet XMLHttpRequest  » issu de CommentCaMarche (www.commentcamarche.net) est mis à disposition sous les termes de la licence Creative Commons. Vous pouvez copier, modifier des copies de cette page, dans les conditions fixées par la licence, tant que cette note apparaît clairement.