Que codificação de caracteres devo usar para um cabeçalho HTTP?


122

Estou usando um caractere especial HTML "divertido" (✰) (consulte http://html5boilerplate.com/ para obter mais informações) para um Servercabeçalho HTTP e estou me perguntando se ele é "permitido" por especificação.

  • Usando a guia Rede nas ferramentas de desenvolvimento do Chrome no Windows Xp Pro SP 3, vejo ✰ muito bem.

  • No IE8, o ✰ não é renderizado corretamente.

  • O validador HTML w3.org não o processa corretamente (exibe " â°" em vez disso).

Bem, não estou muito interessado em codificações de caracteres ... e, francamente, não me importo muito com eles; Eu apenas uso cus UTF-8 porque me disseram para usar. :-)


A disparidade é causada por bugs nos diferentes analisadores / navegadores / motores / (seja lá como forem)?

Existe uma especificação para isso ou talvez uma lista de caracteres permitidos para um "valor" de cabeçalho HTTP?


29
Essa pergunta seria muito melhor geralmente: "Quais caracteres são permitidos em um valor de cabeçalho http"
— Akrikos de


2
"Agora, não estou muito interessado em codificações de caracteres ... e, francamente, eu realmente não me importo muito com eles; eu apenas uso cegamente UTF-8 porque me disseram para fazer. :-)" <--- - Link obrigatório para joelonsoftware.com/2003/10/08/…
— d4nyll

Respostas:


124

Resumindo: apenas ASCII tem garantia de funcionamento. Alguns bytes não ASCII são permitidos para compatibilidade com versões anteriores, mas não devem ser exibidos.

HTTPbis desistiu e especificou que nos cabeçalhos não há codificação útil além de ASCII:

Historicamente, o HTTP permitiu conteúdo de campo com texto no conjunto de caracteres ISO-8859-1 [ISO-8859-1], suportando outros conjuntos de caracteres apenas através do uso da codificação [RFC2047]. Na prática, a maioria dos valores de campo de cabeçalho HTTP usa apenas um subconjunto do conjunto de caracteres US-ASCII [USASCII]. Os campos de cabeçalho recém-definidos DEVEM limitar seus valores de campo a octetos US-ASCII. Um destinatário DEVE tratar outros octetos no conteúdo do campo (obs-text) como dados opacos.


Anteriormente, RFC 2616 de 1999 definia isso:

Palavras de * TEXTO PODEM conter caracteres de conjuntos de caracteres diferentes da ISO-8859-1 [22] somente quando codificados de acordo com as regras da RFC 2047 [14].

e RFC 2047 é a codificação MIME , então seria:

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

mas não acho que muitos (se houver) clientes o suportem.


7
Então, o que isso significa? "✰" é válido / permitido?
— David Murdoch

8
Para expandir um pouco uma resposta muito útil: "UTF-8" é o conjunto de caracteres e "Q" significa que o valor será "imprimível entre aspas". "B" também pode ser usado se você quiser codificar o valor em BASE64.
— GargantuChet

1
@porneL, então o que significa "dados opacos"? O que exatamente o destinatário HTTP deve fazer ao receber esses "dados opacos"?
— Pacerier

1
@Pacerier "dados opacos" significa que é uma caixa preta com um monte de bytes que os aplicativos não deveriam tentar exibir ou interpretar (como dados binários). O que acontece com ele depende do cabeçalho, pode variar de "nada" a "descartar".
— Kornel de

@Kornel, Btw, por que você mudou seu nome de usuário para kornel?
— Pacerier

10

Leia os comentários primeiro, esta resposta provavelmente tira conclusões erradas das fontes certas, precisa ser editada.


Você pode usar qualquer caractere ASCII para impressão, e nenhum caractere especial como ✰ (que não é ASCII )

Dica : você pode codificar qualquer coisa em JSON.

Editar : pode não ser óbvio a princípio, a codificação de caracteres definida no cabeçalho se aplica apenas ao corpo da resposta, não ao cabeçalho em si. (Isso poderia causar um problema de ovo e galinha.)


Eu gostaria de resumir todas as definições relevantes de acordo com as especificações vinculadas por Penchant.

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

Então, estamos atrás do valor do 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 significa Linear White Space. Essencialmente, LWS é Espaço ou Tab, mas você pode quebrar o valor do seu campo em várias linhas, iniciando uma nova linha antes de um Espaço ou Tab.

Vamos simplificar para isso:

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

Agora estamos atrás do conteúdo do 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 é o mais geral e inclui todo o resto - então esqueça o resto-. Aqui está o conjunto de caracteres US-ASCII (= ASCII)

Como você pode ver, todos os caracteres ASCII imprimíveis são permitidos.


3
Você está contradizendo as passagens que citou. Por que você diz "e nenhum caractere especial como ✰"? Os caracteres especiais são apenas OCTETs, e como TEXTqualquer um OCTETexceto 0 - 31, isso significa que todos os OCTETs de 32a 255 são permitidos . Os octetos de ✰ são 226, 156e, 176e todos os três são permitidos, portanto ✰ é permitido de acordo com as passagens que você citou.
— Pacerier

2
@Pacerier você parece completamente certo, não vejo por que cheguei a essa conclusão.
— zupa

@Pacerier ainda não estou pronto para editá-lo, pois precisava verificar as especificações novamente. Temo que detalhes adicionais se restrinjam ao conjunto de caracteres US-ASCII que, por sua vez, apoiaria a conclusão, mas tornaria o raciocínio insuficiente.
— zupa

1
Dizer "você pode codificar qualquer coisa em JSON" é um pouco enganador. JSON permite caracteres Unicode, enquanto os cabeçalhos HTTP devem ser US-ASCII. Os caracteres Unicode seriam tratados como dados "opacos" e, portanto, o comportamento é indefinido pela especificação HTTP. Dito isso, o JSON pode se tornar seguro para inclusão em um cabeçalho HTTP escapando dos caracteres Unicode por meio da sequência de escape \ uXXXX.
— Jacob

@zupa, Outro problema é ... o que significa " excetoCTLs "? Será que isso significa os personagens CR, LFsão permitidos? Ou isso significa que apenas a sequência contínua " CR LF SP/ HT" é permitida? (Por outras palavras, pode conter valores de cabeçalho um único CRou LFou HTvalores de cabeçalho pode conter os caracteres? CR, LFE HTem qualquer ordem e quantidade?)
— Pacerier
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.