54 votes

Détecter le codage des caractères d'une requête HTTP POST

Je suis en train de construire un service web et j'ai un noeud qui accepte un POST pour créer une nouvelle ressource. La ressource attend l'un des deux types de contenu - un format XML que je vais définir, ou des variables codées par formulaire.

L'idée est que les applications consommatrices peuvent POST XML directement et bénéficier d'une meilleure validation, etc., mais il existe également une interface HTML qui POST le contenu codé par formulaire. Il est évident que le format XML comporte une déclaration de jeu de caractères, mais je ne vois pas comment détecter le jeu de caractères du formulaire simplement en regardant le POST.

Un message typique envoyé au formulaire depuis Firefox ressemble à ceci :

POST /path HTTP/1.1
Host: www.myhostname.com
User-Agent: Mozilla/5.0 [...etc...]
Accept: text/html,application/xhtml+xml, [...etc...]
Accept-Language: en-gb,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded
Content-Length: 41

field1=value1&field2=value2&field3=value3

Qui ne semble pas contenir d'indication utile sur le jeu de caractères.

D'après ce que je peux voir, le type application/x-www-form-urlencoded est entièrement défini dans le HTML, qui ne fait qu'énoncer les règles de codage %, mais ne dit rien sur le jeu de caractères que les données doivent utiliser.

En fait, existe-t-il un moyen de connaître le jeu de caractères si je ne sais pas quel était le jeu de caractères du HTML présenté à l'origine ? Sinon, je dois essayer de deviner le jeu de caractères en fonction des caractères présents, ce qui est toujours un peu incertain d'après ce que je sais.

65voto

chburd Points 2902

Le codage par défaut d'un HTTP POST est ISO-8859-1.

sinon vous devez regarder l'en-tête Content-Type qui ressemblera alors à ceci

Content-Type: application/x-www-form-urlencoded ; charset=UTF-8

Vous pouvez peut-être déclarer votre formulaire avec

<form enctype="application/x-www-form-urlencoded;charset=UTF-8">

ou

<form accept-charset="UTF-8">

pour forcer l'encodage.

Quelques références :

http://www.htmlhelp.com/reference/html40/forms/form.html

http://www.w3schools.com/tags/tag_form.asp

10voto

AnthonyWJones Points 122520

Le jeu de caractères utilisé dans le POST correspondra au jeu de caractères spécifié dans le HTML hébergeant le formulaire. Par conséquent, si votre formulaire est envoyé avec un encodage UTF-8, c'est cet encodage qui sera utilisé pour le contenu posté. L'encodage de l'URL est appliqué après que les valeurs ont été converties en un ensemble d'octets pour l'encodage des caractères.

1voto

ZeroConcept Points 151

Essayez de définir le jeu de caractères sur votre Content-Type :

httpCon.setRequestProperty( "Content-Type", "multipart/form-data; charset=UTF-8; boundary=" + boundary );

-2voto

Tor Valamo Points 14209

Les seuls caractères légaux dans une requête HTTP (non multipartite) sont les caractères ASCII* (tout autre caractère est (divisé si codage multi-octets, alors) codé dans le format %xx format). Par conséquent, il importe peu que les données du formulaire soient soumises avec ascii, iso-8859 ou utf-8, car tous les caractères ascii ont la même valeur sur un octet dans les trois codages*. Même s'il s'agissait à l'origine de utf-16, l'encodage du texte HTTP réel serait toujours ascii* !

Les données de formulaires multipartites (téléchargements de fichiers) sont des copies binaires exactes du contenu qu'elles téléchargent et peuvent contenir n'importe quel encodage (bien qu'elles soient toujours représentées en ascii pour la transmission, mais pas nécessairement encodées en url). Ils doivent alors être définis pour l'en-tête content-type de cette partie. Mais jusqu'à ce que vous y arriviez, vous pouvez être sûr à 100% que la requête n'a pas d'encodage différent de ASCII/utf8/iso8859.

* Techniquement, seul l'ASCII de base est accepté, ce qui est source de certaines erreurs d'encodage lorsque vous visitez divers sites web. L'UTF-8 partage le même encodage que l'ASCII, mais uniquement pour les 128 premiers caractères (0-127). Après cela, l'ASCII continue avec l'octet comme 1xxxxxx tandis que l'UTF-8 crée un octet précédent comme suit : 1xxxxxxx 0xxxxxxx . En effet, l'UTF-8/32 (et non 16) utilise le(s) premier(s) bit(s) de chaque octet pour déterminer si l'octet est un octet de tête ou le dernier octet de cette entité particulière. Chaque octet de tête ajoute un autre 1, donc trois octets seraient 11xxxxxx 1xxxxxxx 0xxxxxxx et ainsi de suite. Ainsi, alors que deux octets UTF-8 ne représentent qu'un seul caractère en UTF-8, ils sont interprétés comme deux caractères en ASCII. C'est pourquoi vous devez urlencoder et décoder les métadonnées HTTP (y compris les corps des requêtes). La définition de l'encodage dans l'en-tête content-type est généralement ignorée par les serveurs qui reçoivent les données POST.

J'ai ajouté cette réponse avec quelques années de retard car je cherchais moi-même la même réponse (moment eurêka !).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X