|
| 1 | +--- |
| 2 | +layout: post |
| 3 | +title: Problèmes d'encodage dans une application web |
| 4 | +author: bclozel |
| 5 | +tags: [utf-8, encodage, webapp] |
| 6 | +published: false |
| 7 | +--- |
| 8 | + |
| 9 | +Il n'y a pas de solution miracle lorsqu'on a un problème d'encodage avec |
| 10 | +son application web. Mais avec un peu de méthode et quelques pistes, on |
| 11 | +peut en retrouver la/les sources(s) et les corriger. |
| 12 | + |
| 13 | +## Pour bien comprendre |
| 14 | + |
| 15 | +Tous les développeurs devraient lire au moins une fois ces articles: |
| 16 | + |
| 17 | +* [les chaînes de caractères et |
| 18 | + l'encodage](http://diveintopython3.org/strings.html#htmlboring-stuff) (les paragraphes 4.1 et 4.2 suffisent) |
| 19 | +* [Unicode](http://joelonsoftware.com/Articles/Unicode.html) |
| 20 | + |
| 21 | +Avec ces articles vous comprendrez (entre autres!) pourquoi **vous rencontrez ce problème**, pourquoi **il faut toujours connaître l'encodage d'un texte** et pourquoi **l'UTF-8 vous sauvra**. |
| 22 | + |
| 23 | +Vous le savez maintenant, *détecter l'encodage* d'un texte est une histoire |
| 24 | +de statistiques. Les outils suivants ne peuvent souvent que *deviner* |
| 25 | +l'encodage d'un texte qu'on leur donne: |
| 26 | + |
| 27 | +* `file -i file.txt`: un outil unix se basant sur les headers de fichier |
| 28 | +* `enca`: aussi un outil unix, mais celui-ci se base sur le contenu du fichier |
| 29 | +* [chardet](http://chardet.feedparser.org/), outil python qui se base aussi sur le contenu |
| 30 | + |
| 31 | +Même chose pour vos éditeurs texte et navigateurs préférés: souvent, ils |
| 32 | +essaient seulement de deviner l'encodage ou bien font du "best effort". |
| 33 | + |
| 34 | +## Les outils indispensables |
| 35 | + |
| 36 | +Pour toutes les questions d'encodage, oubliez vos éditeurs de texte |
| 37 | +favoris et ne faites confiance qu'aux outils suivants: |
| 38 | + |
| 39 | +* éditeurs hexa, comme vim: il est de base sur toutes les machines UNIX |
| 40 | + et devrait être [sur votre poste de travail windows](http://www.vim.org/download.php#pc)! |
| 41 | +* des traffic dumpers, comme TCPdump |
| 42 | +* des "strings témoins" (chaînes de caractères avec différents accents, |
| 43 | + pour tester chaque étape) |
| 44 | + |
| 45 | + |
| 46 | +Astuce pour l'édition Hexa dans vim: |
| 47 | + |
| 48 | + gvim -b myfile.txt |
| 49 | + :%!xxd (pour voir la version en Hexa) |
| 50 | + :%!xxd -r (pour reconvertir depuis l'Hexa) |
| 51 | + |
| 52 | + |
| 53 | +## Régler les problèmes d'encodage |
| 54 | + |
| 55 | +### Plan d'ensemble |
| 56 | + |
| 57 | +Voici une architecture "classique" d'une application web Java. Dans la |
| 58 | +suite de l'article, nous allons suivre les maillons de cette chaîne pour |
| 59 | +trouver les problèmes d'encodage. |
| 60 | + |
| 61 | + |
| 63 | + |
| 64 | + |
| 65 | +### Encodage côté base de données |
| 66 | + |
| 67 | +D'abord, vérifier que votre schéma/vos tables utilisent bien le charset |
| 68 | +UTF-8: |
| 69 | + |
| 70 | + SELECT default_character_set_name FROM information_schema.SCHEMATA S |
| 71 | + WHERE schema_name = 'your_schema_name' |
| 72 | + use your_schema_name; |
| 73 | + SHOW TABLE STATUS; |
| 74 | + |
| 75 | +En cas de problème, supprimer et recréer votre schema avec un script SQL |
| 76 | +(ou votre ORM): |
| 77 | + |
| 78 | + drop table if exists mydatabase_table; |
| 79 | + create table mydatabase_table ( [...] ) |
| 80 | + engine=innodb default charset=utf8 collate=utf8_unicode_ci; |
| 81 | + |
| 82 | + |
| 83 | +Attention, ne pas oublier d'indiquer le charset par défaut dans la ligne |
| 84 | +de commande: |
| 85 | + |
| 86 | + mysql --default-character-set=utf8 myutf8_db < mydatabase.sql |
| 87 | + |
| 88 | + |
| 89 | +Si votre base de données a le bon encodage, mais contient des données |
| 90 | +mal encodées, alors référez vous aux rubriques suivantes. |
| 91 | + |
| 92 | +### Connecteur SQL |
| 93 | + |
| 94 | +Cette option n'est pas obligatoire, mais pourrait être la source d'un |
| 95 | +problème d'encodage; il faut alors vérifier la syntaxe de l'URL de |
| 96 | +connexion à la base de données: |
| 97 | + |
| 98 | + connection.jdbc.url = jdbc:mysql://database.pullrequest.org:3306/your_schema_name?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8 |
| 99 | + |
| 100 | +## Connecteur JK |
| 101 | + |
| 102 | +Si vous utilisez un connecteur JK entre Apache et Tomcat, des URLs mal |
| 103 | +encodées peuvent poser problème. |
| 104 | +Il faut alors modifier la configuration du connecteur pour bien encoder |
| 105 | +les caractères non-ASCII dans les URLs: |
| 106 | + |
| 107 | + <connector enablelookups="false" port="10108" protocol="AJP/1.3" redirectport="8443" uriencoding="UTF-8"> |
| 108 | + |
| 109 | +### Headers HTTP client |
| 110 | + |
| 111 | +Parfois, les clients web n'envoient pas les bons Headers HTTP indiquant |
| 112 | +l'encoding des requêtes. |
| 113 | +C'est une source de données utilisateurs mal encodées en base de données; l'utilisation d'un encoding filter doit résoudre le problème. |
| 114 | + |
| 115 | + <filter> |
| 116 | + <filter-name>charsetEncodingFilter</filter-name> |
| 117 | + <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> |
| 118 | + <init-param> |
| 119 | + <param-name>encoding</param-name> |
| 120 | + <param-value>UTF-8</param-value> |
| 121 | + </init-param> |
| 122 | + </filter> |
| 123 | + |
| 124 | + <filter-mapping> |
| 125 | + <filter-name>charsetEncodingFilter</filter-name> |
| 126 | + <url-pattern>/*</url-pattern> |
| 127 | + </filter-mapping> |
| 128 | + |
| 129 | + |
| 130 | +### Les headers HTTP serveur |
| 131 | + |
| 132 | +Il faut alors vérifier les Headers des réponses envoyées par les |
| 133 | +différents serveurs de l'application: Tomcat, Apache/Nginx, etc. |
| 134 | +Pas d'autre solution, il faut requêter ressources statiques (JS), APIs |
| 135 | +serveur, page HTML et vérifier le header `Content-type`. |
| 136 | + |
| 137 | +Les headers HTTP peuvent être écrits par: |
| 138 | + |
| 139 | +* l'application web elle-même |
| 140 | +* les modules apache |
| 141 | +* le conteneur d'application Java |
| 142 | + |
| 143 | + |
| 144 | +### Les balises HTML |
| 145 | + |
| 146 | +Toutes vos pages HTML doivent spécifier un encoding! En HTML5: |
| 147 | + |
| 148 | + <!doctype html> |
| 149 | + <head> |
| 150 | + <meta charset="utf-8"> |
| 151 | + |
| 152 | +### Les fichiers contenant des labels |
| 153 | + |
| 154 | +Même si votre IDE ou votre éditeur texte indique un encoding UTF-8, *il |
| 155 | +ne faut pas trop lui faire confiance*. |
| 156 | + |
| 157 | +Utiliser une string de test et vérifier en Hexa: |
| 158 | + |
| 159 | + “Iñtërnâtiônàlizætiøn” |
| 160 | + E2 80 9C 49 C3 B1 74 C3 AB 72 6E C3 A2 74 69 C3 B4 6E C3 A0 6C 69 7A C3 A6 74 69 C3 B8 6E E2 80 9D |
| 161 | + |
| 162 | +_Autres conseils avec:_ [How to use UTF-8 troughout your web stack](http://rentzsch.tumblr.com/post/9133498042/howto-use-utf-8-throughout-your-web-stack) |
| 163 | + |
0 commit comments