[Plan du site]
Vous êtes ici ---
> Le Site du Zér0
> Les tutoriels
> Non-Officiels
> Site Web
> Javascript
> Lecture du tutoriel
Les objets XMLHttpRequest
Vous vous apprêtez à lire un tutoriel rédigé par un membre de ce site. Malgré tout le soin que ce membre a pu apporter au tutoriel, nous ne pouvons pas garantir que les informations contenues sur cette page sont exactes à 100%. Merci de garder cela en tête lorsque vous lirez cette page ;o)
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).
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.
- 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.
Création de l'instance
Internet Explorer étant, comme d'habitude, un cas à part, il va falloir s'adapter aux différents navigateurs :
Code : JavaScript1
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 : JavaScript1 | 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 : JavaScript1 | 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 : JavaScript1
2 | var data = 'texte='+escape(texte)+'&titre='+escape(titre);
xhr.send(data);
|
Préparation
Le formulaire
Déjà le formulaire, en html bien sûr :
Code : HTML1
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 : HTML1
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 : JavaScript1
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
Code : JavaScript1 | 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 : JavaScript1
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 : PHP1
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.
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.