Несколько слов о <META HTTP-EQUIV...>
Тег <META HTTP-EQUIV ...> был разработан и введен встандарт HTML (он, как минимум, упоминается в Draft на HTML 3.2) для того, чтобы указать HTTP-серверу какие именно заголовки HTTP он может выставить. Как написано в draft HTML-3.2, это именно пожелание для сервера ине более.
Драфт HTML 4.0 в этом смысле более четок - он позволяет WWW-клиенту учитывать тег <META HTTP-EQUIV>
при определении кодировки, но при наличии HTTP-заголовка "Content-Type:... charset=..."
, кодировка должна определяться по HTTP-заголовку.
К сожалению, авторы WWW-броузеров (это относится и к Netscape Navigator и к Microsoft Internet Explorer) либо не читают стандартов, либо читают их как-тостранно. Возможно, у них даже благие намерения. Когда такие броузеры встречают в документе таг:
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=windows1251">
они перестают обращать внимание на корректный (т.е. соответствующий реальной кодировке) HTTP-заголовок Content-Type: и отображают документ в соответствии со своими представлениями об этом Charset (т.е. Netscape меняет шрифт на тот, который установлен для koi8-r, а MS IEперекодирует из KOI8 в cp1251). Более того, эти броузеры обращают внимание на этот тег даже в том случае, когда он встречается внутри <BODY> ... </BODY>
, что уже ни в какие ворота не лезет (интересно, что они будут делать, когда в документе есть несколько противоречивых <META HTTP-EQUIV...>
?).
По большому счету, понятно почему авторы броузеров так поступают - это вполне объяснимое желание быть святее папы римского и одновременно помочь несчастным владельцам серверов с HTTP/0.9 (у этого протокола нет заголовка Content-type).
Эта проблема так и оставалась бы чисто теоретической, но к несчастьюочень распространенные редакторы HTML-файлов (прежде всего MS FrontPage, MS Internet Word Assistant да и много всяких прочих) просто обожают вставлять этот тег в документы и отучить их никак не получается. Таким образом, проблема имеется. Возможных вариантов ее решения несколько:
- Привести содержимое <META HTTP-EQUIV...> в соответствие с реальностью. Этот способ кажется идеальным на первый взгляд, но на самом деле имеет свои недостатки. Основных недостатков два:
- Требуется анализ (парсинг) всех HTML-файлов, выдаваемых сервером от начала и до конца. Анализа только
<HEAD>...</HEAD>
недостаточно т.к. броузеры воспринимают<META>
и внутри<BODY>
. Анализ всех HTML-файлов - процедура достаточно трудоемкая, как для программиста, так и для компьютера; производительность HTTP-сервера может заметно упасть. Впрочем, эта проблема решаема, как минимум теоретически. - HTTP-протокол позволяет запросу (и ответу) от клиента до сервера проходить через произвольное число PROXY-серверов. При этом стандарт явно разрешает PROXY модифицировать содержимое ответа (и запроса), учитывая только данные HTTP-заголовка. Как следствие, перекодирующий PROXY-сервер может перекодировать HTTP-ответ в форму, приемлемую (как думает proxy) для клиента не анализируя сам поток данных. Как следствие, мы получаем ту же проблему - в HTTP-заголовке одно, а в
<META...>
- другое. При этом PROXY делает все в точном соответствии со стандартом и обвинить автора PROXY-сервера ни в чем нельзя. Проконтролировать все возможные PROXY, которые могут находиться между клиентом и сервером тоже невозможно.
- Требуется анализ (парсинг) всех HTML-файлов, выдаваемых сервером от начала и до конца. Анализа только
- Таким образом, мы приходим ко второму очевидному решению -
<META HTTP-EQUIV..>
нужно просто удалять. В этом случае все распространенные броузеры будут использовать значение HTTP-заголовка Content-Type, уважающие себя (и HTTP-протокол) PROXY-серверы тоже будут вести себя корректно. Этот метод воплощен в 'Russian Apache' начиная с версии PL18. - Вообще говоря, есть и третий способ. А именно - увидев в документе
<META HTTP-EQUIV...>
прекратить всяческие попытки перекодировки, поставить HTTP-заголовок Content-Type в соответствующее положение (как предлагает стандарт HTML) и отдать документ AS-IS. Несмотря на соответствие стандартам, использование этого способа в 'Russian Apache' реально невозможно. Например, нельзя отдать документ в кодировке Windows-1251 пользователю, работающему под Unix - у него скорее всего не будет шрифтов, необходимых для чтения этого документа.