Sobre este problema HTML
A norma HTML living standard torna obrigatório o UTF-8 como a única codificação de caracteres permitida para documentos HTML. Codificações legadas como windows-1252, iso-8859-1, shift_jis, e outras eram comuns em páginas web antigas, mas suportam apenas um subconjunto limitado de caracteres. O UTF-8, por outro lado, pode representar todos os caracteres na norma Unicode, tornando-o universalmente compatível entre idiomas e escritas.
Este problema surge tipicamente de uma ou mais destas causas:
-
Declaração
<meta charset>em falta ou incorreta — O seu documento ou não tem uma declaração de charset ou declara explicitamente uma codificação legada como<meta charset="windows-1252">. -
Ficheiro não guardado como UTF-8 — Mesmo com a tag
<meta>correta, se o seu editor de texto guarda o ficheiro numa codificação diferente, os caracteres podem ficar garbled (mojibake). -
O servidor envia um cabeçalho
Content-Typeconflituoso — O cabeçalho HTTPContent-Typepode sobrepor a declaração de charset no documento. Se o seu servidor enviarContent-Type: text/html; charset=windows-1252, o navegador usará essa codificação independentemente do que a tag<meta>diz.
Porque é que isto importa
- Conformidade com normas: A norma WHATWG HTML living standard declara explicitamente que os documentos devem estar codificados em UTF-8. Usar uma codificação legada torna o seu documento não conforme.
-
Internacionalização: Codificações legadas como
windows-1252suportam apenas um conjunto limitado de caracteres da Europa Ocidental. Se o seu conteúdo incluir caracteres fora dessa gama—emoji, caracteres CJK, cirílico, árabe, ou mesmo certas pontuações—não serão renderizados corretamente. - Segurança: Codificações mistas ou ambíguas podem levar a vulnerabilidades de segurança, incluindo certos tipos de ataques de cross-site scripting (XSS) que exploram incompatibilidades de codificação.
- Consistência: Quando a codificação declarada não corresponde à codificação real do ficheiro, os navegadores podem interpretar mal os caracteres, levando a texto garbled que é difícil de depurar.
Como corrigir
Passo 1: Declarar UTF-8 no seu HTML
Adicione uma tag <meta charset="utf-8"> como o primeiro elemento dentro de <head>. Deve aparecer nos primeiros 1024 bytes do documento para que os navegadores a possam detetar cedo.
Passo 2: Guardar o ficheiro como UTF-8
Na maioria dos editores de texto e IDEs modernos, pode definir a codificação do ficheiro:
- VS Code: Clique na etiqueta de codificação na barra de estado inferior e selecione “Save with Encoding” → “UTF-8”.
- Sublime Text: Vá a File → Save with Encoding → UTF-8.
- Notepad++: Vá a Encoding → Convert to UTF-8.
Se o seu ficheiro já contém caracteres codificados em windows-1252, simplesmente mudar a declaração sem recodificar o ficheiro fará com que esses caracteres sejam exibidos incorretamente. Precisa de converter a codificação real do ficheiro.
Passo 3: Verificar a configuração do seu servidor
Se o seu servidor envia um parâmetro charset no cabeçalho HTTP Content-Type, certifique-se de que especifica UTF-8. Por exemplo, no Apache pode adicionar isto ao seu ficheiro .htaccess:
AddDefaultCharset UTF-8
No Nginx, pode defini-lo no seu bloco de servidor:
charset utf-8;
Exemplos
Incorreto: Codificação legada declarada
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="windows-1252">
<title>My Page</title>
</head>
<body>
<p>Hello world</p>
</body>
</html>
Isto desencadeia o erro porque windows-1252 é uma codificação legada.
Incorreto: Usar o formato longo http-equiv com uma codificação legada
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
Esta sintaxe mais antiga também desencadeia o erro quando especifica uma codificação não-UTF-8.
Correto: UTF-8 declarado adequadamente
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>My Page</title>
</head>
<body>
<p>Hello world</p>
</body>
</html>
A tag <meta charset="utf-8"> aparece como o primeiro filho de <head>, e o ficheiro em si deve ser guardado com codificação UTF-8.
Correto: Usar http-equiv com UTF-8
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
Embora a forma mais curta <meta charset="utf-8"> seja preferida, esta sintaxe mais longa também é válida desde que especifique UTF-8.
Encontre problemas como este automaticamente
O Rocket Validator analisa milhares de páginas em segundos, detetando problemas HTML em todo o seu site.