!L’objet XMLHttpRequest
* Auteur : MauriceSvay * Thème : Contenus/Theme/PagesDynamiques (à discuter) * Technologie : Contenus/Technologie/Javascript * Profil : Contenus/Profil/Expert Contenus/Profil/Gourou
!!Remarques *conclusion trop sèche *manque cruel d’un passage sur la réception *des * se sont perdues dans le code js *lien vers l’application fonctionnelle *etoffer les origines *retirer le passage sur DOM3LS
<karlcow> dans http://openweb.eu.org/articles/objet_xmlhttprequest/ <mauriz> oui, il parait que c’est pas exact <karlcow> ;) voila <mauriz> waloo m’a fait la remarque il y’a peu :) <pokute> encore en draft ? <karlcow> mauriz: http://lists.w3.org/Archives/Public/www-dom/2005AprJun/0039.html <mauriz> disons que ça ressemble vaguement de loin <karlcow> mauriz, le problème c’est que tout le monde pense que c’est sensé faire la même chose et que DOM LS n’est pas implémenté. <karlcow> :) DOM 3LS ne gère pas d’interfaces HTTP <mauriz> hum, je vais peut être enlever le passage alors <karlcow> dans XMLHttpRequest (il y a quand même HttpRequest ;) ) <mauriz> en effet :) <karlcow> Tu peux enlever la phrase ou alors être le premier à ne pas raconter de conneries <karlcow> Un truc du genre <karlcow> Beaucoup de gens confondent DOM 3 LS avec XMLHttpRequest <karlcow> etc... blablabla <waloo> mm ? <mauriz> héhé <waloo> ha oui <mauriz> karlcow: c’est noté, ce sera intégré aux corrections que j’ai prévu de faire :) <karlcow> Tu peux même faire un lien vers le mail dans www-dom en disant comme il y a intérêt pour une interface HTTP, un message a été envoyé à la liste DOM pour proposer l’ajout de cette méthode à DOM 3 LS afin de la normaliser. <karlcow> Enfin tu fais comme tu veux, juste des suggestions. <mauriz> je trouverais bien un truc à dire là dessus <karlcow> cool
<waloo> ouais
<waloo> donc
<waloo> j'ai fait un fichier pour définir les classes équivalentes aux implementations ff/khtml/safari pour ie
<waloo> xmlhhtpreq-ms-implem.js
<waloo> @if (@_jscript_version >= 5) {
<waloo> var MS_XMLHTTP_PROGID = ["Msxml2.XMLHTTP.5.0", "Msxml2.XMLHTTP.4.0", "MSXML2.XMLHTTP.3.0", "MSXML2.XMLHTTP", "Microsoft.XMLHTTP"];
<waloo> function get_ms_implem(list) {
<waloo> var msimplem = false;
<waloo> for(var i=0; !msimplem && i < list.length; i++){
<waloo> try{
<waloo> msimplem = new ActiveXObject(list[i]);
<waloo> }
<waloo> catch (e) {
<waloo> msimplem = false;
<waloo> }
<waloo> }
<waloo> return msimplem;
<waloo> }
<waloo> function XMLHttpRequest() {
<waloo> return get_ms_implem(MS_XMLHTTP_PROGID);
<waloo> }
<waloo> @end @*/
<waloo> séparons bien les choses :)
<mauriz> sympa ta fonction pour IE :)
<waloo> la fonction get_ms_implem me permet d'acceder de façon uniforme à XMLHttpRequest XSLTProcessor DOMDocumen
<waloo> j'ai un tableau pour chacun
<mauriz> oui la fonction j'ai pigé ce qu'elle fait :)
<waloo> ce qui permet de faire dans mon code :
<waloo> function getHTTPObject() {
<waloo> var xmlhttp = false;
<waloo> try {
<waloo> xmlhttp = new XMLHttpRequest();
<waloo> }
<waloo> catch (e) {
<waloo> xmlhttp = false;
<waloo> }
<waloo> return xmlhttp;
<waloo> }
<waloo> ( la limite ça sert plus à rien :)))
<mauriz> oui :)
<waloo> enfin j'ai le symétrique :
<waloo> function getXSLTObject() {
<waloo> var xslproc = false;
<waloo> try {
<waloo> xslproc = new XSLTProcessor();
<waloo> }
<waloo> catch (e) {
<waloo> xslproc = false;
<waloo> }
<waloo> return xslproc;
<waloo> }
<waloo> si ça permet de gérer l'implémentation ou non grace à l'exception
<mauriz> oui je vois
<mauriz> mais ça dépasse le cadre d'une mise à jour de l'article
<waloo> vu qu'apres j'ai défini des exceptions pour les réponses http
<waloo> oui sur la partie xslt
<waloo> mais l'idée de mettre tout le code spécifique ie dans un fichier à part est interessane
<mauriz> oui clairement
<waloo> et d'avoir une fonction qui itère sur ces !*@*ù! de versions d'objets actibeX aussi
<mauriz> oui, ça permet d'étendre plus facilement
<waloo> oui
<waloo> voila, je voulais te faire part de ça si tu veux aller plus loin...
<waloo> si t'as des mises à jour prévues
<mauriz> si ça te dérange pas, je vais conserver le log de ce pv sur mon wiki, ça pourrait servir pour la mise à jour de l'article
<waloo> ouais pas de pb
<mauriz> une mise à jour est prévue, j'accumule les remarques pour le moment
<waloo> ok
<mauriz> merci :)
<waloo> heureux de contribuer :)
!!ToDo
*Commenter le code de création de l’objet. *Un chapitre sur le gestionnaire de changement d’état. Déplacer son code ailleurs peut être. *Expliquer d’avantage les propriétés et méthodes. Faire un tableau plus complet avec type de paramètres et de retour? *Discuter l’avenir de cette technologie? *Faire un exemple complet avec un peu de PHP?
!!Abstract
De nouvelles applications web ont vu le jour récemment: recherche avec complétion automatique, interface mail hyperdynamique, cartographie, etc. mais aucune ne fait appel à des plugins tiers comme Flash ou Java. Le secret de leur interface enrichie réside dans l’utilisation intensive de Javascript et d’un objet (dans le sens de la programmation orientée object) en particulier: XMLHttpRequest.
!!1-L’objet XMLHttpRequest?
Créé par Microsoft pour Internet Explorer, l’objet Javascript a été adopté par les navigateurs Mozilla, Konqueror, Safari et récemment Opéra. Bien que largement implémentée dans les navigateurs récents, cette technologie n’est pas un standard du W3C qui propose des fonctionnalités similaires à travers la recommandation [Document Object Model (DOM) Level 3 Load and Save Specification|http://www.w3.org/TR/DOM-Level-3-LS/].
Ce objet permet de faire des requêtes HTTP afin de récuperer des données au format XML qui pourront être intégrées à un document. Cela peut être très utile pour mettre à jour des données sans pour autant recharger la page.
Les avantages possibles: *Diminution de la bande passante : seules les données sont chargées et non plus tout le document *Interactivité accrue: plus de rechargement de la page *Rationnalisation du code: des routines (de vérification par exemple) n’ont plus à être écrites et maintenues dans deux langages (côté client et côté serveur).
Les inconvénients possibles: *Ne fonctionne pas sans Javascript et dans les navigateurs les plus anciens *Ne fonctionne qu’avec HTTP, impossible de récuperer des données sur un disque local (en même temps, c’est normal) *Les requêtes en dehors du domaine provoquent un avertissement de sécurité (à vérifier)
!!2-Créer un objet XMLHttpRequest
L’objet n’étant pas standardisé, son implémentation varie légèrement selon les navigateurs. Alors que Microsoft dispose des fonction ActiveXObject(”Msxml2.XMLHTTP”) et ActiveXObject(”Microsoft.XMLHTTP”), selon le moteur XML utilisé, les autres navigateurs utilisent simplement la fonction XMLHttpRequest(). Pour obtenir un objet lorsqu’il est disponible, inutile de faire des tests sur le navigateur, il suffit de vérifier directement la disponibilité des fonctions.
La code qui suit est une fonction qui renvoie l’objet XMLHttpRequest ou la valeur false lorsque le navigateur ne dispose pas de cette fonctionnalité. C’est aussi dans cette fonction qu’est défini le gestionnaire de changement d’état.
function getHTTPObject() { var xmlhttp = false; /* Compilation conditionnelle d’IE */ /*@cc_on @if (@_jscript_version >= 5) try { xmlhttp = new ActiveXObject(”Msxml2.XMLHTTP”); } catch (e) { try { xmlhttp = new ActiveXObject(”Microsoft.XMLHTTP”); } catch (E) { xmlhttp = false; } } @else xmlhttp = false; @end @*/ if (!xmlhttp && typeof XMLHttpRequest != ‘undefined’) { try { xmlhttp = new XMLHttpRequest(); } catch (e) { xmlhttp = false; } } if (xmlhttp) { on definit ce qui doit se passer quand la page répondra xmlhttp.onreadystatechange=function() { if (xmlhttp.readyState == 4) 4=complete { if (xmlhttp.status == 200) 200=OK { alert(xmlhttp.responseText); traitement de la réponse } } } } return xmlhttp; }
La première partie de la fonction utilise un syntaxe particulière spécifique à Internet Explorer. La seconde partie s’adresse aux autres navigateurs. La troisième partie permet de définir le gestionnaire d’événément qui traitera la réponse.
!!3-Utiliser cet objet
Une fois créé, l’objet peut être manipulé à travers ses propriétés et méthodes:
!!!a-Propriétés
;onreadystatechange : Gestionnaire d’événements pour les changements d’état. Il faut assigner une fonction à cette propriété pour effectuer des traitements sur les données renvoyées après la requête. ;readyState : statut de l’objet Code possibles: *0 = non initialisé *1 = ouverture. La méthode open() a été appelée avec succès. *2 = envoyé. La méthode send() a été appelée avec succès. *3 = en train de recevoir. Des données sont en train d’être transférées mais le transfert n’est pas terminé. *4 = terminé. Les données sont chargées. ;responseText : Réponse sous forme de chaîne de caractères ;responseXML : Réponse sous forme d’objet DOM ;status : code numérique de réponse du serveur HTTP ;statusText : message accompagnant le code de réponse
!!!b-Méthodes
;abort() : abandonne la requête ;getAllResponseHeaders() : Renvoie l’ensemble de l’entête de la réponse sous forme de chaîne de caractères ;getResponseHeader(”champEntete”) : Renvoie la valeur d’un champ d’entête HTTP ;open(”method”, “URL“\[, asyncFlag\[, “userName”\[, “password”\]\]\]): prépare une requête en indiquant la méthode, l’URL, la drapeau de synchronisation, le nom d’utilisateur et le mot de passe. ;send(contenu) : Effectue la requête, éventuellement en envoyant les données ;setRequestHeader(”champ”, “valeur”) : Assigne une valeur à un champ d’entête HTTP qui sera envoyée lors de la requête
!!4-Faire un requête
On considère qu’un gestionnaire d’événement a été assigné à la propriété onreadystatechange. Quelques exemple de requêtes courantes avec les méthodes HEAD, GET et POST.
!!!a-Une requête de type HEAD
var xmlhttp = getHTTPObject(); création de l’objet xmlhttp.open(”HEAD”, “/test.html”,true); Préparation d’une requête asynchrone de type HEAD xmlhttp.send(null); Effectue la requête !!!b-Une requête de type GET var xmlhttp = getHTTPObject(); création de l’objet xmlhttp.open(”GET”, “/test.php?var1=valeur1&var2=valeur2”,true); Préparation d’une requête asynchrone de type GET xmlhttp.send(null); Effectue la requête
!!!c-Une requête de type POST
var xmlhttp = getHTTPObject(); création de l’objet xmlhttp.open(”POST”, “/test.php”,true); Préparation d’une requête asynchrone de type POST xmlhttp.setRequestHeader(’Content-Type’,’application/x-www-form-urlencoded’); xmlhttp.send(”var1=valeur1&var2=valeur2”); //Effectue la requête en envoyant les données
!!5-Conclusion
Même si cette technologie semble pouvoir révolutionner les pratiques, il faut néanmoins l’utiliser avec précautions. Des solutions de repli doivent être prévues pour les personnes ne disposant pas de Javascript. Il est également important de coller au comportement habituel des navigateurs en conservant le rôle des boutons “Précédent” et “Suivant”.
Il faut noter qu’une solution alternative à XMLHttpRequest est l’utilisation d’une frame cachée pour charger de nouvelles données.
!!6-Pour aller plus loin
*[RFC 2616 sur HTTP 1.1|http://www.w3.org/Protocols/rfc2616/rfc2616.html]