4
janvier 08Shoutbox AJAX
Une shoutbox, qu’est-ce-que c’est?
C’est simplement un mini-chat. N’importe qui peut laisser des messages, visibles par tous les visiteurs. Pour vous entraîner, je vous propose une version AJAX et XML. Bien sûr, il est plus facile de le faire grâce à un simple formulaire / traitement PHP-MySQL. Mais la solution AJAX permet d’être intégrée partout car elle ne nécessite aucun refresh. Vous serez libre après de rajouter divers effets Javascript. Je vous propose une application de base.
Le formulaire XHTML
Nous allons passer rapidement sur la création d’un formulaire HTML, car celle-ci ne comporte aucune difficulté.
<div id="shout"> <h1>Shoutbox</h1> <p id="shoutbox"></p> <p id="shout_ajout"> <form id="form_shout"> <input type="text" size="25" id="auteur" onclick="this.value='';" value="Nom" /> <textarea id="txt_shout" rows="2" cols="23" onclick="clean(this);">Texte</textarea> <input type="button" onclick="shout();" value="Shout this !" /> </form> </p> </div>
Un petit point sur les éléments HTML:
- #shout: div globale.
- #shoutbox va accueillir les messages postés par les utilisateurs. Il est vide, nous le remplirons via Javascript.
- #shout_ajout: paragraphe comportant le formulaire.
- #form_shout: formulaire. Chacun de ses champs possède un id qui leur est propre + le bouton d’envoi (qui n’est pas un submit mais un simple bouton).
Traitement asynchrone du formulaire: côté client.
Le traitement du formulaire se fera lors du clic sur le bouton, donc lors de l’appel à la fonction Javascript shout(). Créons la ensemble.
Pour commencer, nous allons récupérer le nom et le texte rentrés par l’utilisateur, grâce à DOM (d’où la nécessité de spécifier des id aux champs du formulaire ):
auteur = document.getElementById("auteur").value; txt_shout = document.getElementById("txt_shout").value;
On peut ensuite tester ces valeurs. On peut vérifier que les champs ont bien été renseignés, ou donner une liste de caractères interdits (qui viendraient compromettre le fichier XML par exemple).
if(auteur != "" && auteur != "Votre nom" && txt_shout != "" && txt_shout != "Votre texte") { if(verif(auteur) && verif(txt_shout)) { [...] } else alert("Desolé, caractère interdit !"); } else alert("Veuillez remplir tous les champs");
Voici, à part, un exemple de fonction de vérification:
function verif(chaine) { var non = new Array("/","'","\"","\\",">","<","<",">"); for (i=0; i<=chaine.length; i++) { for (y=0 ; y <= non.length ; y++) { if ((chaine.charAt(i) == non[y])) return false; } } return true; }
A l’intérieur de notre double condition, dans lesquelles notre script ne rentrera que si les valeurs saisies sont valides, on peut traites les données. Je ne vais pas m’étendre sur la requête AJAX, d’autres l’ont déjà expliqué bien mieux que moi. Explications sur le XHR_object: xul ou toutjavascript.com
Je synthétise: on va appeler de façon asynchrone le fichier include/ajax/shoutXML.php, en lui passant des paramètres en POST: auteur et txt, qui correspondent à nos variables Javascript. Et ça donne:
xhr_object = createXHR(); xhr_object.open("post", "include/ajax/shoutXML.php", true); xhr_object.setRequestHeader('Content-Type','application/x-www-form-urlencoded'); xhr_object.send("auteur=" + auteur + "&txt=" + txt_shout);
Attention, vous avez besoin de ça: un exemple de fonction de création d’un objet XHR.
function createXHR() { var xhr; if(window.XMLHttpRequest) xhr = new XMLHttpRequest(); else if(window.ActiveXObject) { try { xhr = new ActiveXObject("Msxml2.XMLHTTP"); } catch(e) { xhr = new ActiveXObject("Microsoft.XMLHTTP"); } } else xhr = false; return xhr; }
Une fois la requête envoyée, on doit attendre la réponse. Comme expliqué dans les liens ci-dessus, cela se fait grâce à la méthode onreadystatechange. Quand le readystate a atteint l’état « reçu » (soit 4), cela veut dire que les données ont bien été transmises. On peut afficher une éventuelle réponse du serveur (que nous verrons tout à l’heure).
xhr_object.onreadystatechange = function() { if(xhr_object.readyState == 4) { // Affichage du texte document.getElementById("shoutbox").innerHTML = xhr_object.responseText; } }
Voilà , le message a été envoyé. On peut maintenant réinitialiser le formulaire en remettant les valeurs des champs par défaut, et réactualiser la shoutbox. Pour celà , on va appeller la fonction getshout() que l’on codera plus tard.
getshout(); document.getElementById("txt_shout").value = "Texte"; document.getElementById("auteur").value = "Nom";
Côté client, plus rien à faire pour l’instant. Voici le code en un seul morceau:
function shout() { auteur = document.getElementById("auteur").value; txt_shout = document.getElementById("txt_shout").value; if(auteur != "" && auteur != "Votre nom" && txt_shout != "" && txt_shout != "Votre texte") { if(verif(auteur) && verif(txt_shout)) { xhr_object = createXHR(); var fichier = "include/ajax/shoutXML.php"; xhr_object.open("post", fichier, true); xhr_object.setRequestHeader('Content-Type','application/x-www-form-urlencoded'); xhr_object.send("auteur=" + auteur + "&txt=" + txt_shout); xhr_object.onreadystatechange = function() { if(xhr_object.readyState == 4) { document.getElementById("shoutbox").innerHTML = xhr_object.responseText; } } getshout(); document.getElementById("txt_shout").value = "Votre texte"; document.getElementById("auteur").value = "Votre nom"; } else alert("Desolé, caractère interdit !"); } else alert("Veuillez remplir tous les champs"); } function createXHR() { var xhr; if(window.XMLHttpRequest) xhr = new XMLHttpRequest(); else if(window.ActiveXObject) { try { xhr = new ActiveXObject("Msxml2.XMLHTTP"); } catch(e) { xhr = new ActiveXObject("Microsoft.XMLHTTP"); } } else xhr = false; return xhr; } function verif(chaine) { var non = new Array("/","'","\"","\\",">","<","<",">"); for (i=0; i<=chaine.length; i++) { for (y=0 ; y <= non.length ; y++) { if ((chaine.charAt(i) == non[y])) return false; } } return true; }
Le remplissage du fichier XML (côté serveur)
Côté serveur, nous allons remplir un fichier XML. Celui-ci devra avoir la structure d’un flux RSS (on sait jamais). On peut commencer par écrire, en dur, notre fichier XML qui accueillera les items de la shoutbox. Voilà à quoi ça devra ressembler l’en-tête:
<?xml version="1.0" encoding="utf-8"?> <rss xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" version="2.0"> <channel> <title>Shoutbox</title> <link>http://votresite.com</link> <description>Shoutbox de mon site</description> <language>fr</language> <copyright>Open Source =)</copyright> <pubDate>Wed, 28 Feb 2007 10:36:49 +0100</pubDate> <image> <title>NextVal.info</title><url>http://votresite.com/include/img/icone.png</url> <link>http://votresite.com</link> </image>
Et un item:
<item> <title>Fennec</title> <description>COPAIN!!</description> <pubDate>01/01/08</pubDate> <link>http://votresite.com</link> </item> [...] </channel> </rss>
Passons au PHP. Plaçons nous dans le fichier appelé par la requête AJAX: include/ajax/shoutXML.php. Nous avons passé à cet URL deux variables en POST: le nom du posteur, ainsi que son texte. On va donc créer les données dont on a besoin, spécifiques au RSS: un lien, une date, le posteur et le contenu du shout (présents en $_POST):
$lien = "http://votresite.com/"; $auteur = $_POST['auteur']; $date = strftime("%d/%m/%y",time()); $contenu = $_POST['txt'];
Créons maintenant le fichier XML. Nous allons utiliser le simpleXML de PHP5, et y ajouter des noeuds. On commence par ouvrir le fichier (attention au chemin d’accès, relatif à l’url include/ajax/shoutXML.php):
[php]
$doc = simplexml_load_file("../xml/shoutbox.xml");
On se place dans le noeud principal: « channel »:
$xml = $doc->channel;
On y ajoute un noeud « item », que l’on remplit avec nos variables (attention à l’encodage UTF8):
$newShout = $xml->addChild("item"); $newAuteur = $newShout->addChild("title", utf8_encode($auteur)); $newDate = $newShout->addChild("pubDate", utf8_encode($date)); $newContenu = $newShout->addChild("description", utf8_encode(strip_tags($contenu))); $newContenu = $newShout->addChild("link", utf8_encode($lien));
On finit par sauver le fichier :
echo $doc->asXML('../xml/shoutbox.xml');
La methode asXML() renvoie 1 si l’écriture s’est passée correctement. C’est la réponse que le serveur va envoyer au client (PHP -> Javascript). On devrait donc avoir un « 1″ qui s’affiche dans notre shoutbox lors d’un shout, puisqu’on a fait un innerHTML de la réponse du serveur.
C’est tout pour le serveur ! Récapitulatif du code:
<?php $lien = "http://votresite.com"; $auteur = $_POST['auteur']; $date = strftime("%d/%m/%y",time()); $contenu = $_POST['txt']; $doc = simplexml_load_file("../xml/shoutbox.xml"); $xml = $doc->channel; $newShout = $xml->addChild("item"); $newAuteur = $newShout->addChild("title", utf8_encode($auteur)); $newDate = $newShout->addChild("pubDate", utf8_encode($date)); $newContenu = $newShout->addChild("description", utf8_encode(strip_tags($contenu))); $newContenu = $newShout->addChild("link", utf8_encode($lien)); echo $doc->asXML('../xml/shoutbox.xml'); ?>
Récupération du XML via Javascript
On peut retourner dans notre fichier Javascript. Il ne nous reste plus qu’à coder la fonction permettant de rafraîchir la shoutbox, en allant chercher le contenu XML et en l’affichant dans la page. Pour cela, on va utiliser une requete AJAX basique (je détaille moins le code, c’est le même principe que la fonction précédente):
function getshout() { document.getElementById("shoutbox").innerHTML = "Chargement..."; xhr_object = createXHR(); var fichier = "include/ajax/shoutbox.php"; xhr_object.open("post", fichier, true); xhr_object.setRequestHeader('Content-Type','application/x-www-form-urlencoded'); xhr_object.send(null); // Attente de la reponse xhr_object.onreadystatechange = function() { if(xhr_object.readyState == 4) { // Affichage du texte document.getElementById("shoutbox").innerHTML = xhr_object.responseText; } } }
Vous pouvez constater qu’on n’appelle pas la même url. Il va nous falloir créer ce fichier php : include/ajax/shoutbox.php. Celui-ci fera un simple affichage du XML, mis en forme:
<?php $xml = simplexml_load_file("../xml/shoutbox.xml"); $noeuds = $xml->xpath("//item"); for($i=sizeof($noeuds)-1; $i>=0; $i--) { $noeud = $noeuds[$i]; echo "<span class='date'>".$noeud->pubDate."</span>"; echo "<span class='shout_auteur'>Par <strong>".utf8_decode($noeud->title)."</strong></span>"; echo "<span class='shout_contenu'>"; echo "<span class='shout'>".stripslashes(utf8_decode($noeud->description)); echo "</span>\n"; } ?>
Voilà , grâce au innerHTML du javascript, on affichera cela dans la div #shoutbox à l’affichage de cette fonction… qui correspond en fait au simple rafraichissement de la shoutbox (et non de la page complète). On pourra mettre un getshout(); au onload du body de la page, pour que le script aille chercher le contenu de la shoutbox lors de l’affichage de la page:
<body onload="getshout();">Voilà , c’est tout pour aujourd’hui! Voici une archive contenant les sources minimales. A vous de les customiser! N’hésitez pas si vous avez des commentaires, des améliorations, etc.



$lien = « http://votresite.com »;
$auteur = $_POST['auteur'];
$date = strftime(« %d/%m/%y »,time());
$contenu = $_POST['txt'];
Je trouve ça moche d’utiliser des variables en français.
Mais bon, le webmaster est moche aussi donc…
Bubuche le 17 février 2009 à 17:34
Ahah le vrai jaloux @Bubuche !!! Pas possible !!!
Bonne continuation à l’auteur du blog, c’est un excellent blog que je viens de découvrir, et que j’ai partagé ici : http://christopheduman.free.fr/foire-aux-liens
))
s0z le 19 juin 2009 Ã 0:57
Merci pour le lien !
Valentin le 19 juin 2009 Ã 23:30
Tres bonne explication pour comprendre et se perfectionner en ajax !
Dommage le lien vers l’archive ne fonctionne pas.
Bravo en tout cas =)
Flo
Florent le 28 août 2009 à 8:58
Some time ago, I really needed to buy a good house for my firm but I did not have enough cash and couldn’t order something. Thank God my friend adviced to try to get the mortgage loans at trustworthy creditors. So, I did that and used to be happy with my car loan.
ChristyHall le 18 juillet 2010 Ã 23:51
I can tell that you are an professional at your subject! I am launching a website soon, and your information will probably be very useful for me.. Thanks for all of your assistance
nuclear affiliate le 20 juillet 2010 Ã 22:38
seo hosting
seo hosting le 21 juillet 2010 Ã 7:51
it was very interesting to read.
I want to quote your post in my blog. It can?
And you et an account on Twitter?
Nisadoji le 22 juillet 2010 Ã 13:37
I don’t usually reply to articles but I will in this case. Truly a big thumbs up for this 1 C CLass IP hosting!
scierb le 26 juillet 2010 Ã 17:35