Mise à jour du 23/11/2024.
Quiconque a fait du développemet web ou de la programmation s'est un jour heurté à des difficultés d'encodage. Cet article présente un rappel succinct du domaine et comment le gérer lorsque l'on programme des flux à destination de navigateurs.
L'encodage est né de la nécessité de pouvoir afficher plus de 255 caractères. Au début de l'informatique (années 70), 255 caractères suffisaient non seulement à afficher le texte en langue américaine mais encore à disposer de codes de contrôle de périphériques comme les modems, les téléscripteurs ou les imprimantes. Tout cela se faisait au moyen d'une table dont chaque entrée était codées sur un octet et représentait un caractère ou un code de contrôle. Cette table s'appelle la table ASCII et elle est encore massivement utilisée.
L'accès à l'informatique au reste du monde a vite montré les limites de ce faible nombre de caractères. De gros éditeurs comme Microsoft ont alors construit leurs propres tables avant que la normalisation ne vienne mettre un peu d'ordre dans le but de faciliter les échanges de données encodées dans des formats différents.
Le premier réflexe a été d'encoder les caractères sur 16 bits (2 octets) :UTF-16 était né. La difficulté c'est que sur 215 on code tellement de caractères que cette table est souvent trop gourmande en mémoire. L'idée a alors été d'étendre la table ASCII en lui ajoutant un mécanisme de code des caractères non ASCII. On peut ainsi utiliser jusqu'à 4 octets pour coder un caractère spécial (comme le symbole de l'Euro par exemple). Dans la plupart des cas (letres accentuées française par exemple), deux octets suffisent à ce codage. De plus, comme UTF-16, UTF-8 est segmenté et le décodage des caractères spéciaux est une opération rapide. En conséquence, UTF-8 s'est progressivement imposé comme le standard des échanges.
Le langage HTML a trouvé une solution propre pour encoder les caractères spéciaux en les préfixant par le & commercial et en les postfixant par le point-virgule. Par exemple représente l'espace insécable. Pour les langues latines ou nordiques qui utilisent de nombreux symboles diacritiques, cet encodage alourdit la taille des documents HTML et impose un décodage par identification assez coûteux.
L'encodage HTML conserve malgré tout une qualité remarquable : Il sera correctement interprété par les navigateurs quelque soit l'encodage du flux HTTP.
Dans ce domaine, comme dans tous les autres, le poids de l'histoire conduit à des situations complexes pour une solution qui, sans ce poids, serait simple. En effet, les navigateurs ont adopté ISO-8859-1 comme encodage par défaut du flux HTTP lorsque ce dernier n'est pas précisé. Si vous transmettez un flux UTF-8 sans autre précision, vous serez surpris par l'aspect de certains caractères. Par exemple le é codé sur 2 caractères C3 et A8 s'affichera è. Cela est du au fait que les deux octets du codage UTF-8 seront interprétés comme deux caractères de la table ACSII étendue.
Si le flux ne comporte que du code HTML c'est juste "moche". En revanche, s'il contient du code de script là c'est la cata ! Il est donc indispensable de pouvoir indiquer au navigateur quel est l'encodage du flux HTTP qu'il reçoit.
Beaucoup de développeurs pensent que la déclaration <meta charset=utf-8> ou <meta http-equiv="Content-Type" content="text/html; charset=utf-8">> règle ce problème. Ce n'est pas le cas. Ces déclarations sont destinées aux automates qui interprètent le flux HTML, pas aux navigateurs qui interprètent d'abord le flux HTTP et qui, sans précision, suppose que l'encodage par défaut est ISO-8859-1.
En fait, c'est dans l'en-tête HTTP qu'il faut préciser l'encodage via la propriété Content-Type. Pour un flux HTML encodé UTF-8, cette propriété d'en-tête sera : Content-Type: text/html; charset=utf-8. Notez que les anciens navigateurs offraient un choix de menu qui permettaient de "forcer" l'encodage du flux à prendre en compte par le navigateur.
Rédaction par Jean-Marie Piatte (1983-2021)