Quel encodage de caractères dois-je utiliser pour un en-tête HTTP?

122

J'utilise un caractère spécial HTML "amusant" (✰) (voir http://html5boilerplate.com/ pour plus d'informations) pour un Serveren-tête HTTP et je me demande s'il est "autorisé" par spécification.

  • En utilisant l'onglet Réseau dans les outils de développement de Chrome sur Windows Xp Pro SP 3, je vois le ✰ très bien.

  • Dans IE8, le ✰ n'est pas rendu correctement.

  • Le w3.org validateur HTML ne pas rendu correctement (affiche « â°» au lieu).

Maintenant, je n'aime pas trop les encodages de caractères ... et franchement je ne m'en soucie pas trop; J'utilise juste aveuglément UTF-8 car on me dit de le faire. :-)


La disparité est-elle causée par des bogues dans les différents analyseurs / navigateurs / moteurs / (quel que soit leur nom)?

Y a-t-il une spécification pour cela ou peut-être une liste de caractères autorisés pour une "valeur" d'en-tête HTTP?

David Murdoch
la source
29
Cette question serait beaucoup mieux posée en général: "Quels caractères sont autorisés dans une valeur d'en-tête http"
Akrikos
2
"Maintenant, je n'aime pas trop les encodages de caractères ... et franchement je ne m'en soucie pas trop; j'utilise juste aveuglément UTF-8 parce qu'on me dit de le faire. :-)" <--- - Lien obligatoire vers joelonsoftware.com/2003/10/08/…
d4nyll

Réponses:

124

En bref: seul l'ASCII est garanti de fonctionner. Certains octets non ASCII sont autorisés pour la compatibilité ascendante, mais ne sont pas censés être affichables.

HTTPbis a abandonné et a précisé que dans les en-têtes, il n'y avait pas de codage utile en dehors de l'ASCII:

Historiquement, HTTP a autorisé le contenu de champ avec du texte dans le jeu de caractères ISO-8859-1 [ISO-8859-1], prenant en charge d'autres jeux de caractères uniquement grâce à l'utilisation du codage [RFC2047]. En pratique, la plupart des valeurs de champ d'en-tête HTTP n'utilisent qu'un sous-ensemble du jeu de caractères US-ASCII [USASCII]. Les champs d'en-tête nouvellement définis DEVRAIENT limiter leurs valeurs de champ aux octets US-ASCII. Un destinataire DEVRAIT traiter les autres octets du contenu de champ (obs-text) comme des données opaques.


Auparavant, la RFC 2616 de 1999 définissait ceci:

Les mots de * TEXT PEUVENT contenir des caractères de jeux de caractères autres que ISO-8859-1 [22] uniquement lorsqu'ils sont codés selon les règles de la RFC 2047 [14].

et RFC 2047 est le codage MIME , donc ce serait:

=?UTF-8?Q?=E2=9C=B0?=

mais je ne pense pas que de nombreux clients (le cas échéant) le soutiennent.

Kornel
la source
7
Alors qu'est-ce que cela signifie? "✰" est-il valide / autorisé?
David Murdoch
8
Pour développer un peu une réponse très utile: "UTF-8" est le jeu de caractères, et "Q" signifie que la valeur sera "imprimable entre guillemets". "B" peut également être utilisé si vous souhaitez encoder la valeur en BASE64.
GargantuChet
1
@porneL, Alors que signifie «données opaques»? Qu'est - ce exactement le destinataire HTTP doit faire quand il reçoit ces « données opaques »?
Pacerier
1
@Pacerier "données opaques" signifie que c'est une boîte noire avec un tas d'octets que les applications ne devraient pas essayer d'afficher ou d'interpréter (comme des données binaires). Ce qui se passe avec cela dépend de l'en-tête, peut aller de "rien" à "supprimer".
Kornel
@Kornel, Btw pourquoi avez-vous changé votre nom d'utilisateur en kornel?
Pacerier le
10

Veuillez d'abord lire les commentaires, cette réponse tire probablement de fausses conclusions des bonnes sources, doit être modifiée.


Vous pouvez utiliser n'importe quel caractère ASCII imprimable, et aucun caractère spécial comme ✰ (qui n'est pas ASCII )

Astuce : vous pouvez tout encoder en JSON.

Edit : peut ne pas être évident au début, le codage de caractères défini dans l'en-tête ne s'applique que pour le corps de la réponse, pas pour l'en-tête lui-même. (Comme cela causerait un problème de poulet et d'oeuf.)


Je voudrais résumer toutes les définitions pertinentes selon les spécifications liées par Penchant.

message-header = field-name ":" [ field-value ]
field-name     = token
field-value    = *( field-content | LWS )

Donc, nous sommes après field-value .

LWS            = [CRLF] 1*( SP | HT )
CRLF           = CR LF
CR             = <US-ASCII CR, carriage return (13)>
LF             = <US-ASCII LF, linefeed (10)>
SP             = <US-ASCII SP, space (32)>
HT             = <US-ASCII HT, horizontal-tab (9)>

LWS signifie Linear White Space. Essentiellement, LWS est un espace ou une tabulation, mais vous pouvez diviser la valeur de votre champ en plusieurs lignes en commençant une nouvelle ligne avant un espace ou une tabulation.

Simplifions-le à ceci:

field-value    = <any field-content or Space or Tab>

Maintenant, nous sommes après le contenu du champ .

field-content  = <the OCTETs making up the field-value
                 and consisting of either *TEXT or combinations
                 of token, separators, and quoted-string>
OCTET          = <any 8-bit sequence of data>
TEXT           = <any OCTET except CTLs,
                 but including LWS>
CTL            = <any US-ASCII control character
                 (octets 0 - 31) and DEL (127)>
token          = 1*<any CHAR except CTLs or separators>
separators     = "(" | ")" | "<" | ">" | "@"
                 | "," | ";" | ":" | "\" | <">
                 | "/" | "[" | "]" | "?" | "="
                 | "{" | "}" | SP | HT

TEXT est le plus général et inclut tout le reste - oubliez donc le reste -. Voici le jeu de caractères US-ASCII (= ASCII)

Comme vous pouvez le voir, tous les caractères ASCII imprimables sont autorisés.

zupa
la source
3
Vous contredisez les passages que vous avez cités. Pourquoi dites-vous "et pas de caractères spéciaux comme ✰"? Les caractères spéciaux ne sont que des OCTETs, et Since TEXTest n'importe lequel OCTETsauf 0 - 31, cela signifie que tous les OCTETs de 32à 255 sont autorisés . Les octets de ✰ sont 226, 156et 176et trois d'entre eux sont autorisés, donc ✰ est autorisé selon les passages que vous avez cités.
Pacerier
2
@Pacerier vous semblez tout à fait raison, je ne vois pas pourquoi j'ai tiré la conclusion que j'ai faite.
zupa
@Pacerier encore je ne suis pas prêt à le modifier car je devais vérifier à nouveau les spécifications. Je crains que des détails supplémentaires ne se limitent au jeu de caractères US-ASCII qui à son tour soutiendrait la conclusion tout en rendant le raisonnement insuffisant.
zupa
1
Dire "vous pouvez tout encoder en JSON" est un peu trompeur. JSON autorise les caractères Unicode, tandis que les en-têtes HTTP doivent être US-ASCII. Les caractères Unicode seraient traités comme des données "opaques" et le comportement n'est donc pas défini par la spécification HTTP. Cela étant dit, JSON peut être sécurisé pour l'inclusion dans un en-tête HTTP en échappant les caractères Unicode via la séquence d'échappement \ uXXXX.
Jacob
@zupa, Un autre problème est ... que signifie " saufCTLs "? Est -ce que cela veut dire les caractères CR, LFsont autorisés? Ou cela signifie-t-il que seule la séquence continue " CR LF SP/ HT" est autorisée? (En d' autres termes, peut - tête des valeurs contiennent un CRou LFou les HTvaleurs d' en- tête peut contenir les caractères? CR, LFEt HTdans l'ordre et le montant?)
Pacerier