Base de connaissances CCM
Webmestre - Ajax




Sujet 18745 - Utilisation de l'objet XMLHttpRequest

[ Voir ce sujet en ligne ] - [ Catégorie: Webmestre - Ajax ]


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 :

2.3 - Avantages


2.4 - Inconvénients


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 :

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

Instanciation de l'objet XHR

if(window.XMLHttpRequest) 
      xhr_object = new XMLHttpRequest(); 

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:

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 :
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.

Lire la suite

Ajax - Javascript - Upload multiple »
Publié par kij_82 - Dernière mise à jour le 2 novembre 2009 à 14:56 par marlalapocket




Sujet 24380 - Ajax - Javascript - Upload multiple

[ Voir ce sujet en ligne ] - [ Catégorie: Webmestre - Ajax ]



Introduction


AJAX Upload vous permet de facilement télécharger plusieurs fichiers sans rafraîchir la page et utiliser n'importe quel élément pour montrer le fichier fenêtre de sélection. Il fonctionne dans tous les principaux navigateurs et à partir de la version 2.0 ne nécessite pas de bibliothèque à courir. AJAX téléchargement ne pollue pas l'espace de nommage global, il est donc compatible avec jQuery, PrototypeJS, Mootools, et d'autres bibliothèques JavaScript.

Création de l'uploader


Tout d'abord, vous devez créer le bouton. (Vous pouvez utiliser n'importe quel élément).

Exemple :
	<input id="button2" type="file">


Ensuite, vous devez créer une instance upload ajax. Dans sa forme la plus simple, vous pouvez créer en utilisant le code suivant:
	new AjaxUpload('#button2', {
        		action: 'upload.php',
        		onSubmit : function(file , ext){
                		if (! (ext && /^(jpg|png|jpeg|gif)$/.test(ext))){
                        		// extension is not allowed
                        		alert('Error: invalid file extension');
                        		// cancel upload
                        		return false;
                		}
        		}
	});

Script côté serveur (upload.php)


Si vous utilisez PHP, voici un exemple le plus simple :
	$uploaddir = '/var/www/uploads/';
	$uploadfile = $uploaddir . basename($_FILES['userfile']['name']);
	if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile)) 	{
  		echo "success";
	} else {
  		// WARNING! DO NOT USE "FALSE" STRING AS A RESPONSE!
  		// Otherwise onSubmit event will not be fired
  		echo "error";
	}

NB : Il faux ajouter les deux bibliothèques prototype http://www.prototypejs.org/assets/2008/9/29/prototype-1.6.0.3.js

et ajax-upload http://github.com/valums/ajax-upload/raw/master/ajaxupload.js.

Exemple de code source :

	<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
                <script type="text/javascript" src="./prototype.js"></script>
                <script type="text/javascript" src="./ajaxupload.js"></script>

    <script>
		new AjaxUpload('#button2', {
                action: './upload.php',
                onChange : function(file , ext){
                        if (! (ext && /^(jpg|png|jpeg|gif|txt)$/.test(ext))){
                                // extension is not allowed
                                alert('Error: invalid file extension');
                                // cancel upload
                                return false;
                        }
                }
                });
        </script>
    </head>
    <body>
                <form action="#" method="get">
                <input id="button2" type="file">
                </form>
    </body>
</html>


Téléchargement des Fichiers Multiples Génériques en Ajax


On utilisant les même bibliothéques, mais avec des autres techniques javascript
on peut faire l'upload multiple des fichiers.

1- utilisation de DOM Javascript pour créer des lignes de téléchargement.

2- Fonction EVAL Javascript pour evalué l'instance a chaque ligne génerer.

Exemple de code source :

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <script type="text/javascript" src="./prototype.js"></script>
        <script type="text/javascript" src="./ajaxupload.js"></script>

    <script>
    var count_annex = 0;
    var champ_annex = "";
    var annex_suivant = 0;
    function add_annex(id){
    	annex_suivant = count_annex + 1;
	var tbody = $(id).getElementsByTagName("TBODY")[0];
	    var row = document.createElement("TR");
	    var td1 = document.createElement("TD");
	    td1.appendChild(document.createTextNode("column "+annex_suivant));
	    var td2 = document.createElement("TD");
	    td2.innerHTML = '<input type="button" value = "Parcourir" id="annexadded'+count_annex+'"/>';
	    row.appendChild(td1);
	    row.appendChild(td2);
	    tbody.appendChild(row);
	
	eval(new AjaxUpload('#annexadded'+count_annex, {
		action: './upload.php',
		onChange : function(file , ext){
                        if (! (ext && /^(jpg|png|jpeg|gif|txt)$/.test(ext))){
                                // extension is not allowed
                                alert('Error: invalid file extension');
                                // cancel upload
                                return false;
                        }
                	}
		})
		);
	champ_annex = "";
    	count_annex++;
    }
        </script>
    </head>
    <body>
	<table id="myTable" cellspacing="0" border="1">
		<tbody>
		</tbody>
	</table>

	<a href="javascript:add_annex('myTable')">Add row</a>

    </body>
</html>
Publié par wjaouadi - Dernière mise à jour le 26 novembre 2009 à 10:48 par wjaouadi





© Tous droits réservés 2010 Jean-François Pillou