Dans HTTP, vous pouvez spécifier dans une demande que votre client peut accepter un contenu spécifique dans les réponses en utilisant l'en-tête accept
, avec des valeurs telles que application/xml
. La spécification du type de contenu vous permet d'inclure des paramètres dans le type de contenu, tels que charset=utf-8
, indiquant que vous pouvez accepter du contenu avec un jeu de caractères spécifié.
Il y a aussi le accept-charset
en-tête, qui spécifie les encodages de caractères acceptés par le client.
Si les deux en-têtes sont spécifiés et que l'en-tête accept
contient des types de contenu avec le paramètre charset, qui devrait être considéré comme l'en-tête supérieur par le serveur?
par exemple.:
Accept: application/xml; q=1,
text/plain; charset=ISO-8859-1; q=0.8
Accept-Charset: UTF-8
J'ai envoyé quelques exemples de demandes à divers serveurs à l'aide de Fiddler pour tester leur réponse:
Exemples
W
Demande
GET http://www.w3.org/ HTTP/1.1
Host: www.w3.org
Accept: text/html;charset=UTF-8
Accept-Charset: ISO-8859-1
Réponse
Content-Type: text/html; charset=utf-8
Demande
GET http://www.google.co.uk/ HTTP/1.1
Host: www.google.co.uk
Accept: text/html;charset=UTF-8
Accept-Charset: ISO-8859-1
Réponse
Content-Type: text/html; charset=ISO-8859-1
StackOverflow
Demande
GET http://stackoverflow.com/ HTTP/1.1
Host: stackoverflow.com
Accept: text/html;charset=UTF-8
Accept-Charset: ISO-8859-1
Réponse
Content-Type: text/html; charset=utf-8
Microsoft
Demande
GET http://www.Microsoft.com/ HTTP/1.1
Host: www.Microsoft.com
Accept: text/html;charset=UTF-8
Accept-Charset: ISO-8859-1
Réponse
Content-Type: text/html
Il ne semble pas y avoir de consensus sur le comportement attendu. J'essaie d'avoir l'air surpris.
Vous pouvez définir le type de support dans l'en-tête Accept
, la définition du paramètre charset
pour ce type de support n'est définie nulle part dans RFC 2616 (mais ce n'est pas interdit, cependant ).
Par conséquent, si vous prévoyez d'implémenter un serveur compatible HTTP 1.1, vous devez d'abord rechercher Accept-charset
header, puis recherchez vos propres paramètres dans Accept
header.
Lire RFC 2616 Section 14.1 et 14.2. L'en-tête Accept
ne vous permet pas de spécifier un charset
. Vous devez utiliser le Accept-Charset
en-tête à la place.
Tout d'abord, les en-têtes Accept peuvent accepter des paramètres, voir https://tools.ietf.org/html/rfc7231#section-5.3.2
Tous les types text/* mime peuvent accepter un paramètre charset. http://www.iana.org/assignments/media-types/media-types.xhtml#text
L'en-tête Accept-Charset permet à un agent utilisateur de spécifier les jeux de caractères qu'il prend en charge.
Si l'en-tête Accept-Charset n'existait pas, un agent utilisateur devrait spécifier chacun paramètre charset pour chacun texte/* type de support accepté, par exemple.
Accept: text/html;charset=US-ASCII, text/html;charset=UTF-8, text/plain;charset=US-ASCII, text/plain;charset=UTF-8
RFC 7231 section 5.3.2 (Accept
) indique clairement:
Chaque plage de supports peut être suivie de zéro ou plusieurs paramètres de type de support applicables (par exemple, jeu de caractères)
Un paramètre charset pour chaque type de contenu est donc autorisé. En théorie, un client pourrait accepter, par exemple, text/html
seulement dans UTF-8
et text/plain
seulement dans US-ASCII
.
Mais il serait généralement plus logique d'énoncer les jeux de caractères possibles dans le Accept-Charset
header car cela s'applique à tous les types mentionnés dans l'en-tête Accept
.
Si les jeux de caractères de ces en-têtes ne se chevauchent pas, le serveur peut envoyer l'état 406 Not Acceptable
.
Cependant, je ne m'attendrais pas à une correspondance croisée de la part d'un serveur pour diverses raisons. Cela rendrait le code du serveur plus compliqué (et donc plus sujet aux erreurs) alors qu'en pratique, un client rarement enverrait de telles demandes. De plus, de nos jours, je m'attendrais à ce que tout ce qui se trouve sur le serveur utilise UTF-8 et envoyé tel quel, il n'y a donc rien à négocier.