Только что удалось, кажется, более-менее правильно победить давно мучающую читателей "Учебника" проблему, которую на днях снова озвучили.
Проблема, казалось бы, дурацкая и простая, но вот не давалась долгое время. Пишу этот пост-мортем, чтобы мне рассказали, как это сделать еще лучше, и чтобы это потом поисковиками находилось.
Итак, есть статические .html, .css и .js файлы, которые выдаются в неправильной кодировке. Если точнее, они выдаются с сервера вообще без кодировки: ни в самом файле не прописана, ни сервер (lighttpd) ее не выдает. Браузер, соответственно, гадает что-то в области ISO-8859-1, и получается ерунда.
Самое главное для меня — решить эту проблему с минимальной стоимостью поддержки. Проще говоря, чтобы я больше про это никогда не вспоминал.
Вариант прописывания <meta ... >
в файл отпадает, потому что а) про это надо вспоминать в каждом новом файле, б) это не работает для стилей и скриптов.
И вот с научением lighttpd выдавать кодировку я и мучился по сю пору. Там за это отвечает директива mimetype.assign
, в которой должно быть что-то вроде:
mimetype.assign = (
".html" => "text/html; charset=utf-8",
".css" => "text/css; charset=utf-8",
...
)
Однако в Ubuntu'вской сборке lighttpd эта настройка выглядит вот так:
include_shell "/usr/share/lighttpd/create-mime.assign.pl"
Она вызывает скрипт, который генерит большой маппинг для кучи типов, читая его из /etc/mime.types
. В этом файле никаких кодировок быть не может, потому что он не предназначен исключительно для HTTP, это просто карта именно mime-типов, а не заголовков.
Дальше отпадают варианты подхачить скрипт, написать свой скрипт и прописать все mime-типы прямо в конфиг. Потому что если я меняю системные бинаринки или конфиги, то возникает большая вероятность, что при следующем обновлении пакета lighttpd меня будут анноить вопросами про "оставить/заменить/смерджить", а вот этого я как раз хотел избежать.
В итоге пришел к такому решению. Вывод скрипта сдампил в файл /etc/lighttpd/conf-available/mimetypes
и отредактировал там строчки для .htm, .html, .css, .js, подписав к ним "; charset=utf-8". В своем локальном конфиге прописал include этого файла:
$HTTP["host"] =~ "(www.softwaremaniacs.org|softwaremaniacs.org)" {
include "conf-available/mimetypes"
...
}
Поскольку конфиг локальный, пакет lighttpd про него ничего не знает и трогать при обновлениях не будет.
Еще замечу, что важно прописать его именно под условием, а не глобально, потому что иначе lighttpd будет ругаться, что эта настройка — дубликат той, которая так никуда и не делась из системного конфига.
Комментарии: 14 (особо ценных: 1)
text/plain тогда уж добавьте, а вообще — все text/*
Для стилей отлично работает директива,
перед первым правилом. Для скриптов же да, с кодировкой может быть проблема.
зы. Больше про
@charset
: http://www.w3.org/International/questions/qa-css-charsetза это нелюблю убунту и дебиан - жосткие любители испоганить родные конфиги и чего-нить автоматизировать.
в lighttpd есть отличная фича — поддержка замечательного lua. Ваша проблема решается простым скриптом:
Вопрос не в тему - а почему lighttpd, а не nginx?
Есть какие-то производственные показатели?
Ой как все сложно в lighttpd. В nginx все это делается одной опцией в любом месте конфига.
@Антон:
Ой, не надо про простоту ngingx'a! Попробуйте установить кодировку UTF-8 для html'a, который будет отображаться на ошибку 404.
Ребят, а причем тут вообще nginx? Пост про решение одной частной мелкой проблемы с участием разного софта, а не про веб-серверы в целом.
Сдаётся мне, проблема общая — в том, что настроенный конфиг веб-сервера может ни с того ни с сего переписаться дефолтным.
И стоило бы как-то решить её, а не мелко фиксить последствия…
В Ubuntu (в Debian точнее) эта проблема как раз решена. Системные конфиги обычно пишутся так, чтобы include'ить юзерские конфиги из какой-нибудь директории. Именно поэтому у меня и получилось подпихнуть свою карту mime-типов в локальном юзерском конфиге.
Другое дело, что просто синтаксис конфига lighttpd не подразумевает отдельного понятия "charset". Отсюда сложности.
Спасибо, заюзал )
Особо ценный комментарий
Я бы при такой постановке сделал следующее:
Спасибо большое за dpkg-divert, не знал.
Можно после include_shell прописать: