Como informar ao navegador a codificação de caracteres de um site HTML, independentemente do cabeçalho do tipo de conteúdo do servidor?

9

Eu tenho uma página HTML que corretamente (a codificação do físico no disco corresponde a ele) anuncia seu tipo de conteúdo :

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <meta http-equiv="Content-Type" content=
    "text/html; charset=utf-8">
    <title> ...

Abrir o arquivo do disco no navegador (Google Chrome, Firefox) funciona bem.

Solicitando-o via HTTP, o servidor da web envia um cabeçalho de Tipo de Conteúdo diferente:

$ curl -I http://example.com/file.html
HTTP/1.1 200 OK
Date: Fri, 19 Oct 2012 10:57:13 GMT
...
Content-Type: text/html; charset=ISO-8859-1

(veja a última linha). O navegador usa o ISO-8859-1 para exibir qual é um resultado indesejado.

Existe uma maneira comum de substituir os cabeçalhos do servidor enviados ao navegador de dentro do documento HTML?

hakre
fonte

Respostas:

6

"Existe uma maneira comum de substituir os cabeçalhos do servidor enviados ao navegador de dentro do documento HTML?"

AFAIK não, você faz o que já pode fazer. O conjunto de caracteres definido por meio do cabeçalho supera sua definição na tag META.

Se você tiver acesso ao servidor, por exemplo, Apache, ele é configurado por esta declaração (consulte as linhas de comentário):

# Read the documentation before enabling AddDefaultCharset.
# In general, it is only a good idea if you know that all your files
# have this encoding. It will override any encoding given in the files
# in meta http-equiv or xml encoding tags.

#AddDefaultCharset UTF-8

[Atualizar]

Para comentar o segundo do w3d aqui, você encontrará algumas maneiras de alterar o conjunto de caracteres via htaccess-Directives para o servidor Apache.

initall
fonte
2
Os cabeçalhos HTTP +1 substituem as meta tags HTML. Se o @hakre tiver acesso ao lado do servidor, eles também poderão substituir o cabeçalho do Tipo de Conteúdo por página.
MrWhite
3
Certo, aqui está a referência normativa que especifica que HTTP cabeçalhos trunfo meta tags: w3.org/TR/REC-html40/charset.html#h-5.2.2
Jukka K. Korpela
Obrigado pela resposta. @ Korpela: Sim, eu tinha isso na memória com as especificações HTML. É exatamente o contrário como eu preciso dele :(.
hakre
Em relação ao .htaccess (desculpe, isso talvez deva ser uma nova pergunta), é possível remover também o ;charset=...cabeçalho do http. O site funciona muito bem com Content-Type: text/htmlarquivos diferentes com codificações diferentes no servidor. (Receio que isso também não seja possível, porque acho que o procurei há algumas semanas, mas o resultado não foi bem final). Apenas no caso de você poder lançar alguma luz à frente.
21712 hakre
@hakre Se a Diretiva ForceType do Apache funcionar para você, coloque-a em um Contêiner <Files> e nomeie individualmente os arquivos ou determinados diretórios. Apenas deixe a parte "; charset =" após o tipo mime; isso deve ser feito.
initall
3

Você deve definir algo como isso em seu .htaccess raiz

<FilesMatch "\.(htm|html|xhtml|xml|php)$">
    AddDefaultCharset utf-8
</FilesMatch>
PatomaS
fonte
3

Não, não é possível de dentro do HTML. O cabeçalho de resposta dos servidores tem precedência sobre a metatag do documento. Conforme especificado em 5.2.2 Especificando a codificação de caracteres - Especificação HTML 4.01 :

Para resumir, os agentes de usuário em conformidade devem observar as seguintes prioridades ao determinar a codificação de caracteres de um documento (da prioridade mais alta para a mais baixa):

  1. Um parâmetro HTTP "charset" em um campo "Content-Type".
  2. Uma declaração META com "http-equiv" definido como "Content-Type" e um valor definido para "charset".
  3. O atributo charset configurado em um elemento que designa um recurso externo.

Portanto, isso requer configuração no lado do servidor. No entanto, à medida que o capítulo continua:

Os agentes do usuário podem fornecer um mecanismo que permite aos usuários substituir informações incorretas do "conjunto de caracteres". No entanto, se um agente de usuário oferece esse mecanismo, ele deve ser oferecido apenas para navegação e não para edição, para evitar a criação de páginas da Web marcadas com um parâmetro "charset" incorreto.

No meu caso, o cabeçalho Content-Type do servidor contém o tipo MIME correto , mas o conjunto de caracteres errado .

Como se viu, minha configuração httpd do Apache havia AddDefaultCharsetativado o que estava adicionando a ; charset=ISO-8859-1peça. Colocando no diretório raiz do site .htaccessa seguinte linha:

AddDefaultCharset Off

as informações do conjunto de caracteres foram removidas:

$ curl -I http://example.com/file.html
HTTP/1.1 200 OK
Date: Fri, 19 Oct 2012 15:07:52 GMT
...
Content-Type: text/html

(veja a última linha, nenhuma ; charset=...parte). Isso, em combinação com a metatag html, aciona as heurísticas do navegador para assumir o charset da metatag. O site está corretamente decodificado.

Testado com:

  • Google Chrome v. 22.0.1229.94
  • Firefox v. 16.0.1
  • Versão do Lynx 2.8.7rel.1 (05 de julho de 2009)

Esses três navegadores tiveram problemas com a configuração original e funcionam agora (todos no Fedora 17).

  • Opera 12.02
  • Internet Explorer 6 (Win XP SP3)

Não teve o problema em primeiro lugar. Ambos preferiam o UTF-8 da metatag sobre a configuração ISO-8859-1 do servidor.

  • Netscape 2.01 Gold

Como não suporta UTF-8, sempre escolhe Western (Latin1), independentemente da configuração do servidor e da meta tag.

hakre
fonte
1

Além do que foi dito aqui, eu tentaria usar o mesmo conjunto de caracteres em todas as páginas - de preferência UTF-8(mas se quase tudo acontecer iso-8859-1, use isso).

Para verificar rapidamente o conjunto de caracteres de um arquivo, você pode tentar:

file --mime-type --mime-encoding {filename}

Para verificar o conjunto de caracteres de todos os arquivos na árvore, você pode tentar:

find . -type f -exec file --mime-type --mime-encoding '{}' \;

ou (chamando o filecomando apenas uma vez):

find . -type f -print | file --mime-type --mime-encoding -f-

Para obter um resumo, use a -bopção do filecomando (para omitir os nomes dos arquivos) e canalize o resultado para sort | uniq -c.

Tobias
fonte