¿Qué codificación de caracteres debo usar para un encabezado HTTP?

122

Estoy usando un carácter especial HTML "divertido" (✰) (consulte http://html5boilerplate.com/ para obtener más información) para un Serverencabezado HTTP y me pregunto si está "permitido" por especificación.

  • Usando la pestaña Red en las herramientas de desarrollo en Chrome en Windows Xp Pro SP 3, veo el ✰ muy bien.

  • En IE8, ✰ no se representa correctamente.

  • El validador HTML de w3.org no lo representa correctamente (muestra " â°" en su lugar).

Ahora, no estoy muy interesado en las codificaciones de caracteres ... y, francamente, no me importan demasiado; Solo uso ciegamente UTF-8 cus, me dijeron. :-)


¿La disparidad es causada por errores en los diferentes analizadores / navegadores / motores / (como se llamen)?

¿Existe una especificación para esto o tal vez una lista de caracteres permitidos para un "valor" de encabezado HTTP?

David Murdoch
fuente
29
Esta pregunta sería mucho mejor formulada en general: "¿Qué caracteres están permitidos en un valor de encabezado http"
Akrikos
2
"Ahora, no estoy muy interesado en las codificaciones de caracteres ... y, francamente, no me importan demasiado; solo uso ciegamente UTF-8 porque me dicen que lo haga. :-)" <--- - Enlace obligatorio a joelonsoftware.com/2003/10/08/…
d4nyll

Respuestas:

124

En resumen: solo ASCII está garantizado para funcionar. Se permiten algunos bytes que no son ASCII para compatibilidad con versiones anteriores, pero no se supone que se puedan visualizar.

HTTPbis se rindió y especificó que en los encabezados no hay codificación útil además de ASCII:

Históricamente, HTTP ha permitido contenido de campo con texto en el juego de caracteres ISO-8859-1 [ISO-8859-1], admitiendo otros juegos de caracteres solo mediante el uso de la codificación [RFC2047]. En la práctica, la mayoría de los valores de los campos de encabezado HTTP utilizan solo un subconjunto del juego de caracteres US-ASCII [USASCII]. Los campos de encabezado recién definidos DEBEN limitar sus valores de campo a octetos US-ASCII. Un destinatario DEBE tratar otros octetos en el contenido del campo (texto obs.) Como datos opacos.


Anteriormente, RFC 2616 de 1999 definía esto:

Las palabras de * TEXT PUEDEN contener caracteres de conjuntos de caracteres distintos de ISO-8859-1 [22] solo cuando se codifican de acuerdo con las reglas de RFC 2047 [14].

y RFC 2047 es la codificación MIME , por lo que sería:

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

pero no creo que muchos (si es que hay alguno) clientes lo apoyen.

Kornel
fuente
7
¿entonces que significa eso? ¿Es "✰" válido / permitido?
David Murdoch
8
Para ampliar un poco una respuesta muy útil: "UTF-8" es el conjunto de caracteres y "Q" significa que el valor será "entre comillas-imprimible". "B" también se puede utilizar si desea codificar el valor en BASE64.
GargantuChet
1
@porneL, Entonces, ¿qué significa "datos opacos"? ¿Qué exactamente si el receptor HTTP hacer cuando recibe estos datos "opacos"?
Pacerier
1
@Pacerier "datos opacos" significa que es una caja negra con un montón de bytes que las aplicaciones no deberían intentar mostrar o interpretar (como datos binarios). Lo que suceda con él depende del encabezado, puede variar desde "nada" hasta "descartar".
Kornel
@Kornel, por cierto, ¿por qué cambió su nombre de usuario a kornel?
Pacerier
10

Lea los comentarios primero, esta respuesta probablemente extraiga conclusiones incorrectas de las fuentes correctas, necesita editarse.


Puede utilizar cualquier carácter ASCII imprimible y ningún carácter especial como ✰ (que no es ASCII )

Consejo : puedes codificar cualquier cosa en JSON.

Editar : puede que no sea obvio al principio, la codificación de caracteres definida en el encabezado solo se aplica al cuerpo de la respuesta, no al encabezado en sí. (Ya que causaría un problema de huevo y gallina).


Me gustaría resumir todas las definiciones relevantes según la especificación vinculada por Penchant.

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

Entonces, estamos detrás del valor de campo .

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 son las siglas de Linear White Space. Básicamente, LWS es Espacio o Tabulación, pero puede dividir su valor de campo en varias líneas comenzando una nueva línea antes de un Espacio o Tabulación.

Simplifiquemos esto a esto:

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

Ahora buscamos contenido de campo .

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

TEXTO es el más general e incluye todo el resto -así que olvídate del resto-. Aquí está el juego de caracteres US-ASCII (= ASCII)

Como puede ver, se permiten todos los caracteres ASCII imprimibles.

zupa
fuente
3
Está contradiciendo los pasajes que citó. ¿Por qué dices "y sin caracteres especiales como ✰"? Los caracteres especiales son solo OCTETs, y Since TEXTes cualquiera OCTETexcepto 0 - 31, esto significa que se permiten todos los OCTETs desde 32hasta . Los octetos de ✰ son , y , y los tres de ellos se les permite, por lo tanto ✰ está permitido de acuerdo a los pasajes que citó. 255 226156176
Pacerier
2
@Pacerier pareces tener toda la razón, no veo por qué saqué la conclusión que hice.
zupa
@Pacerier todavía no estoy listo para editarlo porque necesitaba volver a verificar la especificación. Me temo que los detalles adicionales se limitan al juego de caracteres US-ASCII, que a su vez respaldaría la conclusión y, sin embargo, haría que el razonamiento fuera insuficiente.
Zupa
1
Decir "puedes codificar cualquier cosa en JSON" es un poco engañoso. JSON permite caracteres Unicode, mientras que los encabezados HTTP deben ser US-ASCII. Los caracteres Unicode se tratarían como datos "opacos" y, por tanto, el comportamiento no está definido por la especificación HTTP. Dicho esto, JSON se puede hacer seguro para su inclusión en un encabezado HTTP al escapar de los caracteres Unicode a través de la secuencia de escape \ uXXXX.
Jacob
@zupa, Otro tema es ... ¿qué significa " exceptoCTLs "? ¿Quiere decir los caracteres CR, LFse permiten? ¿O significa que solo se permite la secuencia continua " CR LF SP/ HT"? (En otras palabras, puede cabecera valores contienen una sola CRo LFo HTvalores de cabecera puede contener los caracteres? CR, LFY HTen cualquier orden y cantidad?)
Pacerier