Détournement des entêtes HTTP en Ajax

Attention: Les informations de ce billet sont susceptibles d'être obsolètes car vieux de plus 2 ans.

Warning: The information you are reading may be obsolete, this post was published more than 2 years ago.

Il existe 3 manières d’utiliser l’objet XMLHTTPRequest pour échanger des informations avec votre serveur. On peut utiliser le support historique qu’est le XML. Le problème étant qu’ensuite il faut parser le fichier XML via javascript avant de pouvoir en utiliser le contenu. Dire que cela est laborieux est un euphémisme, c’est tout simplement chiant à faire. C’est à cause de la complexité de ce traitement que l’utilisation de la notation JSON a gagné en popularité. Avec le JSON plus besoin de parser le XML, les données sont accessibles directement en javascript via la fonction eval de manière natif. Dans le cas où vous ne faites pas confiance à la source de votre flux d’information, le recours à un parser JSON est recommandé. Le problème de cette approche et que si vous ne désirez modifier qu’un élément de votre page contenant plus ou moins beaucoup d’informations, il vous faudra exceller en DOM pour mettre à jour l’affichage de votre page. C’est dans ce dernier cas que la 3ème et dernière technique l’AHAH (Asynchrone Html And HTTP) est approprié. Très simple d’utilisation, l’AHAH combine l’objet l’XMLHTTPRequest et la méthode innerHTML. La modification d’une partie et/ou de l’entièreté de votre page se fait dès lors quasi instantanément. En résumé :

  1. Vous construisez côté serveur la partie HTML que vous désirez ajouter à votre page;
  2. Vous la récupérez via XMLHTTPRequest dans votre page;
  3. Vous l’incluez dans l’élément de votre choix via innerHTML

…et hop c’est dans la boîte. Et voici un exemple pour illustrer mon propos :

Exemple simplifié d’une page PHP côté serveur appelé via XMLHTTPRequest

<?php
header('content-type : text/plain');
$ajax = '<div><p><strong>This is changed via Ajax</strong></p></div>';
echo $ajax;
?>

Côté client on récupère via l’objet XMLHTTPRequest le contenu du fichier PHP en l’occurence $ajax.

//soit XHR l'objet XMLHTTPRequest
if (XHR.readyState === 4) {
if (XHR.status === 200) {  // On a recu une reponse correcte du serveur
document.getElementById('content').innerHTML = XHR.responseText
// XHR.responseText correspond à la valeur de la variable PHP $ajax;
}
}

Le problème avec l’AHAH c’est qu’on ne peut modifie qu’un élément de la page par requête. Que se passe-t-il si l’on veut modifier 2 ou 3 éléments indépendants du site via une une requête HTTP ? Une solution, pour contourner le problème serait de modifier l’entièreté de la page… Mais cela réduit à néant l’avantage de  l’utilisation de l’Ajax. En fait, ce serait bien de combiner la simplicité du AHAH avec une certaine flexibilité que l’on retrouve avec l’utilisation du JSON ou du XML, alors comment faire ?

En regardant de plus près l’objet XMLHTTPRequest on se rend compte que celui-ci possède 2 méthodes méconnues :

  • setResponseHeader, capable de créer et d’envoyer des entêtes HTTP;
  • getResponseHeader, capable de recevoir et de lire les entêtes HTTP.

D’où l’idée totalement immonde de détourner les entêtes HTTP pour envoyer des informations supplémentaires qui me permettraient de changer d’autres aspects de ma page tout en gardant la facilité d’utilisation de la méthode AHAH.

Je sais les puristes me diront que les entêtes HTTP ne servent pas à ça, certains m’ont même dit :

le respect des RFC en matières de proxy HTTP, c’est un peu comme le respect des standards du XHTML strict par les développeurs web.

Sachant que ma technique est un peu barbare, je me suis restreins dans l’utilisation de celle-ci. C’est déjà assez mal de le faire alors je ne l’utilise que pour envoyer vers mon client des informations minimales de type :

  • pseudo booleéns (ex: ‘t/f’ ou ‘KO/OK’);
  • des nombres;

Mais rien n’empêcherait un esprit mal intentionné d’envoyer encore plus d’informations via cette méthode… bien que je ne le recommande pas. Encore une fois je le dis, les requêtes HTTP ça sert pas à ça.  Avec mes requêtes HTTP “fait maison” j’envoie donc des données pouvant entrainer des changements locaux contrôler par javascript en suivant la méthode suivante :

Côté serveur, on aura :

<?php
header('content-type :text/plain');
$ajax = '<div><p><strong>This is changed via Ajax</strong></p></div>';
// $condition est la résultante de ce que le serveur a recu comme requete via Ajax
$http_header = ($condition === true) ? 'OK' : 'KO';
header('x-sajax-condition :' . $http_header, true);
echo $ajax;
?>

et au niveau de mon javascript je récupère l’information très simplement

//soit HR l'objet XMLHTTPRequest
if (XHR.readyState === 4) {
if ( HR.status === 200) {  // On a recu une reponse correcte du serveur
var cond = HR.getResponseHeader('x-sajax-condition');
if (/OK/.test(cond)) {
//changement si la condition est OK
} else {
//changement si la condition est KO
}
document.getElementById('content').innerHTML = HR.responseText;
}
}

Et voila, que pensez-vous de cela… C’est mal, je sais, pensez-vous qu’il existe une autre manière pour obtenir la même fléxibilité tout en utilisant l’AHAH ? Si oui, je suis preneur 😉 .

3 thoughts on “Détournement des entêtes HTTP en Ajax

  1. Pingback: www.fuzz.fr
  2. if (/OK/.test(cond)) …

    Et après on s’étonne que je trouve que le JS c’est le grand langage du n’importe quoi… 🙂

  3. @Salagir : quand on voit que le JS permet de prototyper toutes les classes de base (c’est un énorme point fort quand c’est bien utilisé) et qu’une de ses librairies les plus connues se nomme… Prototype (et n’a _RIEN_ à voir), on comprend bien que l’ensemble de la communauté manque un peu de rigueur…
    Ceci dit sans offense, bien sûr 🙂

    @nyams: merci d’avoir cité mon blog dans les références (c’est la classe!).

Leave a Reply to Didier_S Cancel reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.