Окт
16
2011

«Правильная» utf-8 кодировка в настройках nginx/apache

Правильная utf-8 кодировка в настройках nginx/apacheНадеюсь, что данный пост окажется полезным многим разработчикам, т.к. судя по многочисленным тредам в интернете, проблема-то довольно частая. Суть проблемы в следующем: неправильное наименование кодировки utf-8 в настройках nginx/apache. При этом отдаваемый сервером контент воспринимается нормально во всех браузерах, кроме Internet Explorer-a.
 
 

Зачастую, многие разработчики, при конфигурации виртуальных хостов копируют настройки откуда-нибудь из интернета или же из других мест. И при этом в их настройки «перекочевывает» ошибка. В случае nginx это директива:

charset utf8;

В случае Apache это:

<Directory /path/to/site/>
 AddDefaultCharset UTF8
</Directory>

Так вот — нет такой кодировки как utf8! Правильно писать utf-8 (через дефис). Большинство браузеров (Firefox >= 3, Opera >= 9, Chrome >= 4, Safari >= 4) лояльно относятся к указанию utf8 в качестве кодировки, и воспринимают отдаваемый контент корректно, а вот все версии Internet Explorer (включая даже последнюю, 9ую) вместо контента выдают «кракозябры». Конечно же эта ситуация легко обходится даже без исправления настроек web-сервера. Так, например, в случае отдачи динамического контента с использованием PHP, можно явно указывать кодировку в самом скрипте:

header('Content-type: text/html; charset=utf-8');

Или же использовать в HTML следующий тег:

<meta http-equiv="content-type" content="text/html; charset=utf-8" />

И все бы хорошо, но ситуация усложняется когда посредством AJAX JavaScript пытается достучаться до статического контента. Пример с использованием jQuery:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$(document).ready(function(){
    function print_r()
    {
      //...
    }
    $.ajax({
        url: "/test.txt",
        dataType: "text",
        success: function(data, textStatus){
            $('#res').html(data);
        },
        error: function(jqXHR, textStatus, errorThrown) {
            var errorTxt  = 'jqXHR: ' + print_r(jqXHR);
                errorTxt += '<br />textStatus: ' + textStatus;
                errorTxt += '<br />errorThrown: ' + print_r(errorThrown);
            $('#res').html(errorTxt);
        }
    });
});

В данном случае IE выдает ошибку следующего характера:

{
  jqXHR: {
    readyState: 4,
    status: 0,
    statusText: 'error'
  },
  textStatus: 'error',
  errorThrown: {
     name: 'Error',
     number: -1072896658,
     description: 'Не удалось завершить действие. Ошибка c00ce56e.',
     message: 'Не удалось завершить действие. Ошибка c00ce56e.'
  }
}

Данная JS ошибка достаточно нетривиальна. И если пользователи, кто уже сталкивался с подобным, сразу сообразят в чем дело, то у тех, кто сталкивается с подобным впервые, может возникнуть недоумение и уйти много времени на выяснение причины.

P.S Мой аналогичный пост на хабре.
P.S.S Как было верно подмечено в комментариях на Хабре, при обращении к MySQL для указания в какой кодировке обращаться к БД используется запрос:

SET NAMES utf8

Да и вообще везде, где идет ссылка на кодировку utf-8, например при создании таблицы:

CREATE TABLE `some_table` () ENGINE=innoDB DEFAULT CHARSET=utf8

кодировка указывается utf8, а не utf-8. То есть в данном случае запись идет БЕЗ дефиса, что вносит ещё больший когнитивный диссонанс в понимание происходящего…

Комментарии (6)

  • вместо «text/html; charset», лучше «text/html;charset»

    • ммм… возможно, а почему? пока не вижу разницы если честно.

      • Однажды работая с AJAX (через ExtJS) и Internet Explorer (версию не помню, проверял одновременно на 6-9 версиях) была проблема с приемом JSON-данных в нужной кодировке. Очень удивился, когда пробел проблему неожиданно решил.

        Проблему с пробелом я находил в интернете, правда там шла речь про сервер IIS… но, тем не менее…

        • Интересная фишка — помню когда работал с ExtJS, тоже были проблемы с кодировками и AJAX response-ами, но на проблему пробелов не натыкался. Спасибо — возьму на заметку!

  • Сталкнулся с данной проблемой, друг попросил написать несколько скриптов на аяксе, и ИЕ конечно же ругался. Спасибо большое за статью!

  • Молоток, спасибо.

Оставить комментарий на Влад.

CAPTCHA image


Поля, отмеченные * обязательны для заполнения


XHTML: Вы можете использовать следующие теги: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="" highlight="">