Para respostas HTTP com os tipos de conteúdo sugerindo dados de caracteres, qual charset deve ser assumido pelo cliente se nenhum for especificado?
-
22-09-2019 - |
Pergunta
Se nenhum parâmetro de charset for especificado no cabeçalho do tipo de conteúdo, RFC2616 Seção 3.7.1 Parece sugerir que a ISO8859-1 deve ser assumida para os tipos de mídia de "texto" do subtipo:
Quando nenhum parâmetro explícito de charset é fornecido pelo remetente, os subtipos de mídia do tipo "texto" são definidos como tendo um valor de charset padrão de "ISO-8859-1" quando recebido via http.
Dados em conjuntos de caracteres que não sejam "ISO-8859-1" ou seus subconjuntos devem ser rotulados com um valor apropriado do charset.
No entanto, eu vejo rotineiramente aplicativos que servem arquivos JavaScript com valores do tipo conteúdo como "Application/X-Javascript" (ou seja, nenhum param de charset), mesmo quando esses scripts contêm caracteres não-ASCII UTF-8, que seriam corrompidos se interpretados como ISO8859-1.
Isso não parece representar problemas para os clientes. Como os clientes sabem interpretar os bytes como UTF-8? Existe uma regra para outros subtipos de dados de caracteres que implica que o UTF-8 deve ser o padrão? Onde isso está documentado?
Solução
Todos os principais navegadores que verifiquei (ou seja, FF e ópera) completamente Ignore a especificação RFC nesta parte.
Se você estiver interessado no algoritmo para detectar automaticamente o charset por dados, veja Mozilla Firefox link.
Apenas uma pequena nota sobre os tipos de conteúdo: Apenas o texto tem conjuntos de personagens. É razoável supor que os navegadores lidam com o aplicativo/x-javascript da mesma forma que lidam com o texto/javascript (exceto o IE6, mas esse é outro assunto).
Internet Explorer usará o charset padrão (provavelmente armazenado no registro), conforme observado:
Por padrão, o Internet Explorer usa o conjunto de caracteres especificado no tipo de conteúdo HTTP retornado pelo servidor para determinar esta tradução. Se este parâmetro não for fornecido, o Internet Explorer usará o conjunto de caracteres especificado pelo meta elemento no documento. Ele usa as preferências do usuário Se nenhum elemento meta for especificado.
Fonte: http://msdn.microsoft.com/en-us/library/ms537500%28vs.85%29.aspx
Mozilla Firefox Tentativas de detectar automaticamente o charset, como apontado aqui:
Este artigo apresenta três tipos de métodos de detecção automática para determinar as codificações de documentos sem declaração explícita de charset.
Fonte: http://www.mozilla.org/projects/intl/universalcharsetDetection.html
Ópera Também usa detecção automática, conforme documentado:
Se o protocolo de transporte fornecer um nome de codificação, é usado. Caso contrário, a Opera analisará a página para uma declaração de charset. Se isso estiver faltando, a ópera tentará detectar automaticamente a codificação, usando o nome de domínio para ver se o script é um script CJK e, se sim, qual. Opera também pode detectar automaticamente o UTF-8.
Outras dicas
Conforme descrito em RFC 4329, também application/javascript
pode ter um charset
parâmetro. A outra questão é o tratamento de implementações do navegador. Desculpe, mas não testado.
Na ausência do charset
parâmetro, a codificação do caractere pode ser especificada no contente. Aqui estão algumas abordagens adotadas por vários tipos de conteúdo:
Html - via META TAG:
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
Html5 variante:
<meta charset="utf-8">
Xml (Xhtml, kml) - via Declaração XML:
<?xml version="1.0" encoding="UTF-8"?>
Texto - via Marca de pedidos de byte. Por exemplo, para UTF-8 Os três primeiros bytes de um arquivo em hexadecimal:
EF BB BF
Como distinto do conjunto de caracteres associado ao documento, observe também que caracteres não-ASCII podem ser codificados por meio de sequências de caracteres ASCII usando várias abordagens:
Html - Através da referências de personagens:
&#nnnn;
&#xhhhh;
Xml - Através da referências de personagens:
&
&defined-entity;
JSON - via mecanismo de fuga:
\u005C
\uD834\uDD1E
Agora, com relação ao protocolo HTTP 1.1, RFC 2616 diz isso sobre o charset:
O parâmetro "charset" é usado com alguns tipos de mídia para definir o conjunto de caracteres (Seção 3.4) dos dados. Quando nenhum parâmetro explícito de charset é fornecido pelo remetente, os subtipos de mídia do tipo "texto" são definidos como tendo um valor de charset padrão de "ISO-8859-1" quando recebido via http. Dados em conjuntos de caracteres que não sejam "ISO-8859-1" ou seus subconjuntos devem ser rotulados com um valor apropriado do charset. Consulte a Seção 3.4.1 para problemas de compatibilidade.
Então, minha interpretação do exposto é que um não podes assuma um conjunto de caracteres padrão exceto Para subtipos de mídia do tipo "texto". Obviamente, vivemos no mundo real e os implementadores nem sempre seguem as regras. Conforme descrito no resposta aceita, os vários fornecedores de navegador da Web implementaram suas próprias estratégias para determinar o conjunto de caracteres de documentos quando não é especificado explicitamente. Pode -se assumir que os fornecedores de outros clientes (por exemplo, Google Earth) também implementam suas próprias estratégias.
RFC 4329 Define o tipo de mídia "Application/JavaScript" como um substituto para "texto/javascript", "aplicativo/x-javascript" e outros tipos semelhantes. A Seção 4.2 estabelece a codificação de caracteres padrão para ser UTF-8 quando nenhum parâmetro explícito "charset" está disponível e nenhum unicode BOM está presente na frente dos dados.
É um pouco especial para xmlhttprequest e é descrito aqui: http://www.w3.org/tr/xmlhttprequest/
Apontar o óbvio: "Application/X-Javascript" não é um subtipo de "texto".
Além disso, o texto na RFC 2616 está desatualizado. A próxima revisão do HTTP/1.1 não definirá um padrão. Consulte RFC 6657 para obter mais informações.