Aller au menu - Aller au contenu

Les objets XMLHttpRequest


Informations sur le tutoriel

Avatar
Auteur : 6(sic)6
Visualisations : 53 482


Plus d'informations Plus d'informations
Les objets XMLHttpRequest permettent d'exécuter des requêtes sur le serveur sans recharger la page actuelle. Grâce à cette technique, vous pourrez par exemple appeler une page PHP (à la suite d'un clic sur un lien ou un bouton, entre autres) qui ira chercher des informations dans votre base de données pour ensuite les renvoyer à JavaScript qui les traitera ; tout ça sans que le visiteur ne s'aperçoive de rien. ;)

Ce tuto va vous montrer comment utiliser ces objets pour créer une fonction d'aperçu de votre BBCode PHP (comme par exemple la fonction Aperçu final du SDZ).

Prérequis

Notions de JavaScript



Vous aurez besoin d'un minimum de connaissances en JavaScript pour bien suivre ce tuto : variables, fonctions, objets, structures, ...
Il existe pas mal de tutos sur internet expliquant ça plus ou moins bien ; quelques liens :



L'AJAX



Rien à voir avec la lessive ou le club de foot bien entendu, AJAX signifie Asynchronous JavaScript And XML. On désigne par là l'association du JavaScript et d'un autre langage, pour notre cas ici, le PHP ; ce n'est donc pas un langage à part entière.
L'AJAX permet d'exécuter des requêtes asynchrones sur le serveur (c'est-à-dire indépendantes du chargement de la page, mais en fonction de l'utilisateur) et ainsi de permettre de nouvelles possibilités. Pour cette raison, l'AJAX suscite actuellement un engouement auprès des développeurs web.

Choses à savoir sur les objets XMLHttpRequest



Les méthodes



  • open(string method, string url, bool async)
    Ouvre la connexion avec le serveur.
    • method : définit le mode de transfert des données, GET ou POST ; POST est conseillé
    • url : adresse de la page avec laquelle JavaScript va dialoguer ('apercu.php' par exemple)
    • async : définit si le transfert doit être synchrone (false, défaut) ou asynchrone (true), asynchrone est conseillé
  • send(string content)
    Envoie la requête.
    • content : contenu de la requête ; null si le mode de transfert est GET, sinon elle doit être de la forme var1=val1&var2=val2
  • abort()
    Abandonne la requête.
  • setResponseHeader(string label, string value)
    Établit une en-tête HTTP.
    • label : nom de l'en-tête
    • value : valeur de l'en-tête
  • getResponseHeader(string label)
    Obtenir le contenu d'un en-tête HTTP.
    • label : nom de l'en-tête
  • getAllResponseHeaders()
    Obtenir les contenus de toutes les en-têtes HTTP.


Les propriétés



  • readyState
    Statut de l'objet.
    • 0 : non initialisé
    • 1 : ouverture du transfert
    • 2 : données envoyées
    • 3 : les données arrivent
    • 4 : données arrivées
  • onreadystatechange
    Contiendra notre fonction qui traitera les informations à chaque changement de readyState.
  • status
    Code HTTP du statut de la requête (404, 200, ...).
  • statusText
    Message correspondant à status.
  • responseText
    Données reçues, envoyées par le serveur, au format texte.
  • responseXML
    Données reçues, envoyées par le serveur, au format XML.


Très théorique tout ça, je l'avoue :-° .
Nous n'utiliserons pas toutes ces méthodes et propriétés par la suite ; celles que nous utiliserons seront expliquées, ne vous inquiétez pas ^^ . C'était juste pour faire un récapitulatif.

Le BBCode PHP



Le but de ce tuto n'étant pas de créer un BBCode, je vais vous donner une petite fonction qui gère quelques balises juste pour l'exemple (pas du niveau du SdZ hein ^^ ) :

bbcode.php
Code : PHP
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
<?php
function bbcode_parse($texte)
        {
        $texte = nl2br(htmlentities($texte,ENT_QUOTES));
        $texte = preg_replace('`\[color=(.+)\](.+)\[/color\]`iUs','<span style="color:$1;">$2</span>',$texte);
        $texte = preg_replace('`\[b\](.+)\[/b\]`iUs','<span style="font-weight:bold;">$1</span>',$texte);
        $texte = preg_replace('`\[i\](.+)\[/i\]`iUs','<span style="font-style:italic;">$1</span>',$texte);
        $texte = preg_replace('`\[u\](.+)\[/u\]`iUs','<span style="text-decoration:underline;">$1</span>',$texte);
        $texte = preg_replace('`\[url=(.+)\](.+)\[/url\]`iUs','<a href="$1">$2</a>',$texte);
        $texte = preg_replace('`\[img\](.+)\[/img\]`iUs','<img src="$1" alt="Image" />',$texte);
        return $texte;
        }
?>


Passons à un peu plus de pratique maintenant. :)

Utilisation des objets XMLHttpRequest

Création de l'instance



Internet Explorer étant, comme d'habitude, un cas à part, il va falloir s'adapter aux différents navigateurs :

Code : JavaScript
1
2
3
4
var xhr; // on déclare l'instance
if (window.XMLHttpRequest) xhr = new XMLHttpRequest(); // Firefox, Opera, Konqueror, Safari, ...
else if (window.ActiveXObject) xhr = new ActiveXObject('Microsoft.XMLHTTP'); // Internet Explorer
else alert('JavaScript : votre navigateur ne supporte pas les objets XMLHttpRequest...'); // Navigateur ancien


Jusque là, pas de difficultés : on créé l'instance en fonction du navigateur du visiteur, et si il n'est pas compatible on affiche une erreur.

Connexion



Il faut ensuite se connecter au fichier du serveur qui traitera les informations, grâce à la méthode open. Elle prendra trois arguments : le type de transfert des données, on va mettre 'POST' ; l'adresse de la page qui va traîter les données, par exemple 'js_xhr.php' ; et le caractère asynchrone du transfert, que l'on va mettre à true (synchrone signifie ici que le script sera figé le temps de la requête (correspond à une "pause"), asynchrone permet à l'utilisateur de continuer de naviguer tranquillement sur la page pendant l'exécution du script).

Code : JavaScript
1
xhr.open('POST','js_xhr.php',true);


La méthode étant POST, le nom de fichier suffit. Mais si nous avions choisi GET, l'url aurait dû être de la forme fichier.ext?var1=val1&var2=val2, comme pour un script PHP qui récupère les variables par $_GET.
Ici nous aurions pu mettre, si la méthode avait été GET, 'js_xhr.php?texte='+texte+'&titre='+titre

Attribution d'une fonction à onreadystatechange



On va devoir faire quelque chose dont vous n'avez peut-être pas l'habitude : attribuer une fonction à une propriété.
onreadystatechange sera appelée à chaque changement de la valeur de readyState (voir plus haut). Ce que nous voulons, c'est récupérer responseText quand readyState vaut 4 (4 qui signifie "prêt") et en faire ce que nous voulons.
Démonstration :

Code : JavaScript
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
xhr.onreadystatechange = function() // attribution de la fonction
        {
        if (xhr.readyState == 4)
                {
                // mettre ici ce que nous voulons faire de responseText
                
                // par exemple
                document.write(xhr.responseText);
                
                // ou
                alert(xhr.responseText);
                }
        }


Cette fonction sera donc appellée quatre fois : quand readyState va passer de 0 à 1, de 1 à 2, de 2 à 3 et de 3 à 4. Le seul moment qui nous intéresse est le passage de 3 à 4 (4 qui signifie que la requête est terminée et que les données sont prêtes, je le rappelle), on va donc tester la valeur de readyState, et si elle vaut 4, exécuter le code que l'on veut pour récupérer les données.

Header HTTP pour méthode POST



Si vous utilisez la méthode POST, il ne faut pas oublier de placer l'en-tête Content-Type (pour GET ce n'est pas la peine) :

Code : JavaScript
1
xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');


Envoi de la requête



Si notre requête avait été de type GET, nous aurions dû mettre xhr.send(null);. Mais POST nécessite de formater une chaîne contenant les données : si vous devez transférer deux variables vous devrez faire comme ça (forme var1=val1&var2=val2) :

Il faut utiliser la fonction escape() pour échapper les caractères spéciaux.


Code : JavaScript
1
2
var data = 'texte='+escape(texte)+'&titre='+escape(titre);
xhr.send(data);

Fonction d'aperçu

Préparation



Le formulaire



Déjà le formulaire, en html bien sûr :

Code : HTML
1
2
3
4
5
<form method="post" action="index.php">
<p><label>Texte :<br />
<textarea name="bbcode" rows="10" cols="50"></textarea></label><br />
<input type="submit" name="submit" value="Envoyer" /></p>
</form>


L'aperçu



Pour l'aperçu, on va avoir besoin de mettre en place un bouton pour lancer l'aperçu, et un bloc div vide qui aura un attribut id, pour pouvoir y accéder avec JavaScript.

Code : HTML
1
2
3
4
5
6
7
<form method="post" action="index.php">
<p><label>Texte :<br />
<textarea name="bbcode" rows="10" cols="50"></textarea></label><br />
<input type="submit" name="submit" value="Envoyer" /></p>
<p><input type="button" name="apercu_bbcode" value="Aperçu" onclick="apercu(this.form,'apercu');" /></p>
</form>
<div id="apercu"></div>


On a également dû mettre un onclick pour que notre future fonction d'aperçu s'exécute au moment du clic sur le bouton.

Modifier l'affichage



Reste encore à savoir comment afficher l'aperçu à l'écran.
Pour ça, il faut utiliser la méthode getElementById() et la propriété innerHTML.
Leur utilisation s'effectue comme ça :

Code : JavaScript
1
2
3
4
if (document.getElementById)
    {
    document.getElementById('apercu').innerHTML = '<strong>texte</strong>';
    }


Avec ce code, l'élément ayant l'id apercu aura comme "valeur" '<strong>texte</strong>'.

La fonction d'aperçu en elle-même



Base de la fonction



Comme nous l'avons vu plus haut, les requêtes XMLHttpRequest s'effectuent ainsi :

Code : JavaScript
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
function apercu()
    {
    var xhr; // création de l'instance de l'objet
    if (window.XMLHttpRequest) xhr = new XMLHttpRequest();
    else if (window.ActiveXObject) xhr = new ActiveXObject('Microsoft.XMLHTTP');
    else
        {
        alert('JavaScript : votre navigateur ne supporte pas les objets XMLHttpRequest...');
        return;
        }
    xhr.open('POST','js_xhr.php',true); // ouverture de la connexion
    xhr.onreadystatechange = function() // définition de la fonction de traitement
        {
        if (xhr.readyState == 4)
            {
            //traitement des données
            }
        }
    xhr.setRequestHeader('Content-type','application/x-www-form-urlencoded'); // en-tête HTTP
    var data = 'texte='+escape(texte); // formatage de la requête
    xhr.send(data); // envoi de la requête
    }


Arguments de la fonction



La fonction aura deux arguments : f (le formulaire) et id (l'id du div).
La variable texte devra correspondre au contenu du formulaire.

Code : JavaScript
1
function apercu(f,id)


Code : JavaScript
1
var texte = f.bbcode.value; // contenu du formulaire


Traitement des données



Pour ça, on va utiliser la propriété innerHTML à laquelle on va donner la valeur de xhr.responseText.

Code : JavaScript
1
2
3
4
5
6
7
xhr.onreadystatechange = function()
    {
    if (xhr.readyState == 4)
        {
        if (document.getElementById) document.getElementById(id).innerHTML = xhr.responseText;
        }
    }




Et voilà notre fonction terminée :

Code : JavaScript
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function apercu(f,id)
    {
    var texte = f.bbcode.value;
    var xhr;
    if (window.XMLHttpRequest) xhr = new XMLHttpRequest();
    else if (window.ActiveXObject) xhr = new ActiveXObject('Microsoft.XMLHTTP');
    else
        {
        alert('JavaScript : votre navigateur ne supporte pas les objets XMLHttpRequest...');
        return;
        }
    xhr.open('POST','js_xhr.php',true);
    xhr.onreadystatechange = function()
        {
        if (xhr.readyState == 4)
            {
            if (document.getElementById) document.getElementById(id).innerHTML = xhr.responseText;
            }
        }
    xhr.setRequestHeader('Content-type','application/x-www-form-urlencoded');
    var data = 'texte='+escape(texte);
    xhr.send(data);
    }


Le PHP



Il ne reste maintenant plus qu'à créer le fichier js_xhr.php qui s'occupera de transformer le BBCode en HTML.

Admettons que la fonction bbcode_parse() que j'ai donnée au début soit dans le fichier bbcode.php.
PHP devra inclure cette page, et ensuite faire un echo de la fonction bbcode_parse() avec comme argument le BBCode du formulaire.
Il faut aussi utiliser la fonction header pour placer une en-tête.

js_xhr.php
Code : PHP
1
2
3
4
5
<?php
header('Content-type: text/html; charset=iso-8859-1'); // en-tête HTTP
include('bbcode.php'); // pour la fonction bbcode_parse()
echo nl2br(htmlentities(bbcode_parse($_POST['texte']),ENT_QUOTES)); // on affiche le html
?>


La méthode de transfert étant POST, les variables récupérées sont dans la variable superglobale $_POST (si ça avait été GET, la variable aurait été $_GET, bien sûr) avec le nom que vous avez mis lors du formatage de la requête (nous avions mis 'texte='+escape(texte), donc la variable est $_POST['texte']).

Améliorations



Bien sûr, ce code est améliorable :

  • désactiver le bouton d'aperçu le temps de la requête, avec f.apercu_bbcode.disabled = true;
  • n'exécuter la requête uniquement si le formulaire n'est pas vide
  • rajouter des fonctions au BBCode
  • ...


Faites travailler votre imagination. ;)

Q.C.M.

Quel est le nom donné à la technologie alliant la Javascript et un langage serveur ?
Quelle valeur de la propriété readyState signifie que les données ont été transférées et que le script est prêt ?
Quelle propriété de getElementById() permet de modifier la valeur HTML d'un élément de la page ?

Statistiques de réponses au QCM


Cette introduction aux objets XMLHttpRequest n'est qu'un aperçu des choses rendues possibles. C'est PHP qui travaille, JavaScript reçoit uniquement les informations, vous pourrez donc ainsi modifier des fichiers du serveur, enregistrer du texte ou autre dans la base de données, renvoyer l'heure du serveur et non plus celle du client, ...
Après, à vous d'imaginer à quoi pourraient vous servir ces objets, et en quoi ils pourraient perfectionner votre site. ;)

Informations sur le tutoriel

Retour en haut Retour en haut

Créé : Le 16/01/2006 à 18:23:04
Modifié : Le 22/08/2008 à 16:08:32
Avancement : 100%
Licence : Copie non autorisée

55 commentaires