Как сообщить браузеру кодировку символов веб-сайта HTML независимо от заголовка типа содержимого сервера?

9

У меня есть HTML-страница, которая правильно (кодировка физического на диске соответствует этому) объявляет его 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> ...

Открытие файла с диска в браузере (Google Chrome, Firefox) работает нормально.

Запрашивая его через HTTP, веб-сервер отправляет другой заголовок Content-Type:

$ 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

(см. последнюю строку). Затем браузер использует ISO-8859-1 для отображения, что является нежелательным результатом.

Есть ли общий способ переопределить заголовки сервера, отправляемые в браузер из документа HTML?

hakre
источник

Ответы:

6

«Есть ли общий способ переопределить заголовки сервера, отправляемые в браузер из документа HTML?»

AFAIK нет, вы делаете то, что вы уже можете сделать. Определенная кодировка через заголовок превосходит ваше определение в теге META.

Если у вас есть доступ к серверу, например, Apache, он настраивается этим оператором (см. Строки комментариев):

# 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

[Обновить]

Ко второму комментарию w3d вы найдете несколько способов изменить кодировку через директивы htaccess для сервера Apache.

initall
источник
2
+1 HTTP заголовки переопределяют метатеги HTML. Если у @hakre есть доступ к серверной части, они также могут переопределить заголовок Content-Type для каждой страницы.
MrWhite
3
Правильно, вот нормативная ссылка, которая указывает, что заголовки HTTP имеют преимущество перед
Юкка К. Корпела
Спасибо за ответ. @Korpela: Да, у меня было это в памяти со спецификациями HTML. Это как раз наоборот, как мне нужно :(.
Хакре
Что касается .htaccess (извините, это может быть новый вопрос вместо этого), можно ли удалить также ;charset=...из заголовка http. Сайт работает очень хорошо Content-Type: text/html, разные файлы имеют разные кодировки на сервере. (Боюсь, что это тоже невозможно, потому что я думаю, что искал это несколько недель назад, но результат был не совсем окончательным). На всякий случай вы можете пролить свет прямо перед собой.
Хакре
@hakre Если директива ForceType Apache работает для вас, поместите ее в контейнер <Files> и по отдельности присвойте имена файлам или определенным каталогам. Просто оставьте часть "; charset =" после mime-типа, тогда это должно быть сделано.
начало
3

Вы должны установить что-то подобное в своем корне .htaccess

<FilesMatch "\.(htm|html|xhtml|xml|php)$">
    AddDefaultCharset utf-8
</FilesMatch>
PatomaS
источник
3

Нет, это невозможно изнутри HTML. Заголовок ответа сервера имеет приоритет над метатегом документа. Как указано в 5.2.2 Указание кодировки символов - HTML 4.01 Спецификация :

Таким образом, соответствующие пользовательские агенты должны соблюдать следующие приоритеты при определении кодировки символов документа (от наивысшего приоритета к низшему):

  1. HTTP-параметр "charset" в поле "Content-Type".
  2. Декларация META с http-эквивалентным значением «Content-Type» и значением, установленным для «charset».
  3. Атрибут charset установлен для элемента, который обозначает внешний ресурс.

Так что это требует настройки на стороне сервера. Однако, как продолжается глава:

Пользовательские агенты могут предоставлять механизм, который позволяет пользователям переопределять неверную информацию «кодировки». Однако, если пользовательский агент предлагает такой механизм, он должен предлагать его только для просмотра, а не для редактирования, чтобы избежать создания веб-страниц, помеченных неверным параметром «charset».

В моем случае заголовок Content-Type сервера содержит правильный mime-тип, но неправильную кодировку .

Как оказалось, в моей конфигурации Apache httpd была включена функция AddDefaultCharsetдобавления ; charset=ISO-8859-1части. Поместив в корневой каталог сайтов .htaccessследующую строку:

AddDefaultCharset Off

информация о кодировке была удалена:

$ 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

(см. последнюю строку, без ; charset=...части). Это в сочетании с метатегом html запускает указанную эвристику браузера, чтобы перенять кодировку из метатега. Сайт правильно декодирован.

Протестировано с:

  • Google Chrome v. 22.0.1229.94
  • Firefox v. 16.0.1
  • Рысь версия 2.8.7rel.1 (05 июля 2009)

Эти три браузера имели проблемы с исходной конфигурацией и теперь работают (все на Fedora 17).

  • Опера 12.02
  • Internet Explorer 6 (Win XP SP3)

Во-первых, не было проблемы. Оба предпочитали UTF-8 из мета-тега по сравнению с настройкой ISO-8859-1 с сервера.

  • Netscape 2.01 Gold

Не поддерживает UTF-8, поэтому всегда выбирает Western (Latin1) независимо от настроек сервера и метатега.

hakre
источник
1

В дополнение к тому, что было сказано здесь, я бы попробовал использовать одну и ту же кодировку на всех страницах - желательно UTF-8(но, если почти все так iso-8859-1, используйте это).

Чтобы быстро проверить кодировку файла, вы можете попробовать:

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

Чтобы проверить кодировку всех файлов в дереве, вы можете попробовать:

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

или (вызывая fileкоманду только один раз):

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

Чтобы получить сводку, используйте -bопцию для fileкоманды (чтобы опустить имена файлов) и направьте результат в sort | uniq -c.

Тобиас
источник