Pull to refresh

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

Website development *
Надеюсь, что данный пост окажется полезным многим разработчикам, т.к. судя по многочисленным тредам в интернете, проблема-то довольно частая. Суть проблемы в следующем: неправильное наименование кодировки 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:
$(document).ready(function(){
    function print_r()
    {
      //...
    }
    $.ajax({
        url: "/test.txt",
        dataType: "text",
        success: function(data, textStatus){
            $('#res').html(data);
        },
        error: function(jqXHR, textStatus, errorThrown) {
            $('#res').html('jqXHR: ' + print_r(jqXHR) + '<br />textStatus: ' + textStatus + '<br />errorThrown: ' + print_r(errorThrown));
        }
    });
});

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

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

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

Да и вообще везде, где идет ссылка на кодировку utf-8, например при создании таблицы:
CREATE TABLE `some_table` (… ) ENGINE=innoDB DEFAULT CHARSET=utf8

кодировка указывается utf8, а не utf-8. То есть в данном случае запись идет БЕЗ дефиса, что вносит ещё больший когнитивный диссонанс в понимание происходящего…
Tags:
Hubs:
Total votes 163: ↑143 and ↓20 +123
Views 91K
Comments Comments 72