Un des facteurs qui a limité l’adoption de XHTML est sans aucun doute le fait que Internet Explorer n’accepte pas le type média « application/xhtml+xml » : bien que ce soit le type média officiel des documents XHTML et bien qu’Internet Explorer sache afficher les documents XHTML, si vous lui présentez un document avec ce type média il ne l’affiche pas mais propose à l’utilisateur de le sauvegarder ou des chercher une application capable de lire ce document.
Autrement dit, IE n’accepte les documents XHTML que s’ils se font passer pour des documents HTML!
A l’inverse, un navigateur tel que Firefox qui accepte le type média « application/xhtml+xml » affichera également vos documents XHTML si vous les faites passer pour des documents HTML, mais il les traitera très naturellement comme des documents HTML ce qui peut poser problème dans certains cas.
La solution idéale est donc de détecter si le navigateur accepte des documents XHTML et de présenter des documents XHTML ou HTML suivant le résultat de cette détection.
Cette fonctionnalité est proposée par Orbeon Forms bien qu’elle n’est pas mise en œuvre dans les installations par défaut. Pour la rendre opérationnelle, il suffit d’enlever les commentaires qui entourent la détection et le traitement différencié HTML/XHTML dans le pipeline epilogue-servlet.xpl.
Ce pipeline est exécuté pour effectuer les mises en formes finales et envoyer les documents aux navigateurs dans le cas où l’application est exécutée dans un servlet.
Le test correspondant est le suivant :
<p:choose href="#request"> <p:when test="contains(/request/headers/header[name = 'accept'], 'application/xhtml+xml')"> ...
Sans être spécialiste Orbeon Forms, vous aurez compris qu’il s’agit de tester, dans un document XML représentant la requête HTTP, s’il y a une entête dont le nom est « accept » et qui contienne la chaîne de caractères « applications/xhtml+xml ».
L’élégance de la chose est qu’au lieu de tester qu’il s’agit ou non d’Internet Explorer, vous testez si le navigateur accepte les documents de type « application/xhtml+xml ». On peut donc espérer que ce test fonctionne quelque soit le navigateur et si IE accepte un jour ce type de document nous n’ayons pas à changer ce test pour que des documents XHTML lui soient servis.
Et ça marche : Firefox reçoit effectivement des documents XHTML et IE reçoit des documents HTML.
Sauf que… cela ne devrait pas marcher!
Si vous regardez une requête HTTP envoyée par IE, vous verrez quelque chose comme :
Accept: */* Accept-Language: fr Accept-Encoding: gzip, deflate If-Modified-Since: Mon, 24 Dec 2007 08:52:18 GMT User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows 98) Host: localhost:8080 Connection: Keep-Alive
Au lieu de donner une liste des types de documents acceptés, IE utilise un joker et prétend accepter tout les types de documents.
Le test effectué par Orbeon Forms n’est pas conforme à la RFC 2616 puisqu’il ignore les jokers qui sont pourtant décrits dans la RFC. De plus, la RFC spécifie également qu’en l’absence d’entête « accept », il faut considérer que le navigateur accepte tout les types de documents.
Pour le rendre plus conforme à la RFC, il faut écrire :
<p:choose href="#request">
<!-- See http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html -->
<p:when
test="contains(/request/headers/header[name = 'accept'], 'application/xhtml+xml')
or contains(/request/headers/header[name = 'accept'], 'application/*')
or contains(/request/headers/header[name = 'accept'], '*/*')
or not(/request/headers/header[name = 'accept'])">
C’est encore un test un peu simpliste puisqu’il accepterait des types erronés tels que « mon-application/* » mais il est réagit correctement aux entêtes conformes à la spécification.
Ceci dit, le test étant maintenant correct, IE reçoit la version XHTML des documents puisqu’il déclare accepter ce type de document et il faut ajouter un deuxième test avec un traitement spécifique pour ce navigateur…
C’est ce qui est fait dans la version du pipeline epilogue-servlet.xpl utilisé par la version actuelle de la planète XMLfr.
Outre le fait que la réponse d’Internet Explorer, bien qu’étant conforme à la norme soit absolument inutile pour un serveur Web, ce qui me semble intéressant dans cette affaire, c’est la manière dont un test simple mais erroné fonctionne dans la majorité des cas pour de mauvaises raisons!