¿Cómo decirle al navegador la codificación de caracteres de un sitio web HTML independientemente del encabezado de tipo de contenido del servidor?

9

Tengo una página HTML que correctamente (la codificación del físico en el disco coincide con ella) anuncia que es Content-Type :

<!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 el archivo desde el disco en el navegador (Google Chrome, Firefox) funciona bien.

Al solicitarlo a través de HTTP, el servidor web envía un encabezado de tipo de contenido 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

(ver última línea). El navegador luego utiliza ISO-8859-1 para mostrar cuál es un resultado no deseado.

¿Hay alguna forma común de anular los encabezados del servidor enviados al navegador desde el documento HTML?

hakre
fuente

Respuestas:

6

"¿Hay alguna forma común de anular los encabezados del servidor enviados al navegador desde el documento HTML?"

AFAIK no, ya haces lo que puedes hacer. El conjunto de caracteres definido a través del encabezado supera su definición en la etiqueta META.

Si tiene acceso al servidor, por ejemplo, Apache, está configurado por esta declaración (vea las líneas de comentarios):

# 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

[Actualizar]

Para el segundo comentario de w3d aquí, encontrará algunas formas de cambiar el juego de caracteres a través de las directivas htaccess para el servidor Apache.

initall
fuente
2
Los encabezados HTTP +1 anulan las metaetiquetas HTML. Si @hakre tiene acceso al lado del servidor, también podrían anular el encabezado Content-Type por página.
MrWhite
3
Bien, aquí está la referencia normativa que especifica que los encabezados HTTP triunfan sobre las metaetiquetas: w3.org/TR/REC-html40/charset.html#h-5.2.2
Jukka K. Korpela
Gracias por la respuesta. @ Korpela: Sí, tenía eso en memoria con las especificaciones HTML. Es exactamente al revés, ya que lo necesito :(.
hakre
Con respecto a .htaccess (lo siento, esta podría ser una pregunta nueva), ¿es posible eliminar también el ;charset=...encabezado http? El sitio funciona muy bien Content-Type: text/html, los diferentes archivos tienen diferentes codificaciones en el servidor. (Me temo que esto tampoco es posible, porque creo que lo busqué hace algunas semanas pero el resultado no fue del todo definitivo). En caso de que puedas arrojar algo de luz justo delante.
Hakre
@hakre Si la Directiva ForceType de Apache funciona para usted, colóquela en un Contenedor <Files> y nombre individualmente los archivos o ciertos directorios. Simplemente deje la parte "; charset =" después del tipo mime, esto debería hacerlo.
initall
3

Debería establecer algo como esto en su raíz .htaccess

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

No, no es posible desde el HTML. El encabezado de respuesta del servidor tiene prioridad sobre la metaetiqueta del documento. Como se especifica en 5.2.2 Especificación de la codificación de caracteres - Especificación HTML 4.01 :

En resumen, los agentes de usuario conformes deben observar las siguientes prioridades al determinar la codificación de caracteres de un documento (de la prioridad más alta a la más baja):

  1. Un parámetro HTTP "charset" en un campo "Content-Type".
  2. Una declaración META con "http-equiv" establecido en "Content-Type" y un valor establecido para "charset".
  3. El atributo charset establecido en un elemento que designa un recurso externo.

Por lo tanto, esto requiere configuración en el lado del servidor. Sin embargo, a medida que el capítulo continúa:

Los agentes de usuario pueden proporcionar un mecanismo que permita a los usuarios anular la información incorrecta del "juego de caracteres". Sin embargo, si un agente de usuario ofrece dicho mecanismo, solo debería ofrecerlo para navegar y no para editar, para evitar la creación de páginas web marcadas con un parámetro "charset" incorrecto.

En mi caso, el encabezado Content-Type del servidor contiene el tipo mime correcto pero el juego de caracteres incorrecto .

Al final resultó que, mi configuración httpd de Apache había configurado el AddDefaultCharsetencendido que estaba agregando la ; charset=ISO-8859-1parte. Colocando en el directorio raíz del sitio web .htaccessla siguiente línea:

AddDefaultCharset Off

se eliminó la información del juego de caracteres:

$ 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

(Ver última línea, sin ; charset=...parte). Esto, en combinación con la metaetiqueta html, activa dichas heurísticas del navegador para hacerse cargo del conjunto de caracteres de la metaetiqueta. El sitio web está correctamente decodificado.

Probado con:

  • Google Chrome v. 22.0.1229.94
  • Firefox v. 16.0.1
  • Lynx Versión 2.8.7rel.1 (05 de julio de 2009)

Estos tres navegadores tenían problemas con la configuración original y funcionan ahora (todos en Fedora 17).

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

No tuve el problema en primer lugar. Ambos preferían UTF-8 de la metaetiqueta sobre la configuración ISO-8859-1 del servidor.

  • Netscape 2.01 Gold

No es compatible con UTF-8, por lo que siempre elige Western (Latin1) independientemente de la configuración del servidor y la metaetiqueta.

hakre
fuente
1

Además de lo que se dijo aquí, intentaría usar el mismo juego de caracteres en todas las páginas, preferiblemente UTF-8(pero si casi todo es así iso-8859-1, use esto).

Para verificar rápidamente el conjunto de caracteres de un archivo, puede intentar:

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

Para verificar el conjunto de caracteres de todos los archivos en el árbol, puede intentar:

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

o (llamando al filecomando solo una vez):

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

Para obtener un resumen, use la -bopción del filecomando (para omitir los nombres de archivo) y canalice el resultado a sort | uniq -c.

Tobias
fuente