Вот уже полтора года в draft-ах пылился пост о надуманности проблем с кодировками и т.н. AJAX-ом.
Каждый раз, когда на форумах всплывали вопросы подобного характера, хотелось дать ссылку, на всякий всплеск заходов на блог по запросам “кодировка, ajax, проблема” хотелось его опубликовать, но мне казалось, что пост ещё не закончен, надо ещё чуть-чуть дописать…
Но вот буквально сегодня появился удивительно похожий пост – ajax, cp1251. Похожий по содержанию, но совершенно противоположный по смыслу.
Посему свой черновичок я решил удалить, а поведать свою “истину” в форме критики совета fxposter-а.

Ни для кого ни секрет, что кодировкой получаемых через Ajax данных по-умолчанию принимается UTF-8.

На самом деле это секрет. Для многих секрет. И многие не понимают почему это так.
Внутреннее представление строк (и регулярных выражений) в JavaScript для всех не-ASCII последовательностей как раз UTF-8.
Отсюда и проистекает т.н. “проблема” – если кодировка не указана явно и используется нелатиница, она будет интерпретирована как utf-8 последовательность.

Update 29.11 Свежий воздух и Давид Мзареулян остудили пыл, поэтому спешу уточнить о чём именно будет идти речь ниже.
Итак – у вас есть некий ресурс в однобайтовой кодировке (к гадалке не ходи это будет windows-1251) и вы озаботились освоить новый buzzword по имени AJAX. Немного почитав, вы делаете первые робкие шаги в этом направлении и тут же наступаете на “детские грабли”, а затем, немного отдышавшись, мчитесь на форумы с криком о помощи. И вам эту помощь окажут – переделай мол, свой ресурс на utf-8… Конечно-конечно скажете вы и пойдёте переделывать…
Я же хочу остеречь от таких опрометчивых шагов.

Cтандартное решение, которое наперебой советуют все – “используй utf-8 и нет проблем”.

И советчики правы – проблем действительно не будет.

Просто трафик увеличится “вдвое”. Те же данные, тот же результат, а трафика “в два раза” больше. Ага?

Что вы там говорите насчёт порошка?!?

Если вам этот фактор кажется мало***щим, то на этом чтение надо прекратить и начать переделывать свой проект на использование UTF-X,
остальным же оставлю несколько рецептов, которые помогут избежать проблем при использовании однобайтовых кодировок в т.н. AJAX-приложениях:

  • Первое, оно же главное – ВСЕГДА указывайте кодировку контента. В любом ответе сервера с текстовым контентом обязан быть заголовок Content-Type: your/type; charset=your-charset.
    Дешевле всего это сделать, настроив сервер (например в php через default_charset)
  • Указывайте charset при включении javascript в тело документа (<script type="text/javascript" charset="your-charset"> )
  • Указывайте ПРАВИЛЬНЫЙ charset

    предварительно установив соответствующий заголовок – “Content-Type: text/html; charset=cp1251”

    В данном конкретном взятом за жопу случае fxposter сам себе злобный буратина.

    Any registered IANA charset may be used, but UTF-8 is preferred.

    Ну нету среди any registered кодировки с названием cp1251…

Для полноты картины приведу пару проблемных моментов, с которыми столкнуться прийдётся:

  • Не позволяйте AJAX-ответам, которые содержат “нелатиницу” оставаться в кеше браузера (при 304 Not Modified ответ поднимется из кеша, но в качестве charset “некоторые браузеры” используют utf-8)
  • JSON text SHALL be encoded in Unicode. The default encoding is UTF-8.

    Этим правилом НАГЛО пользуются производители различных библиотек для json_[en|de]code, но браузерам (как мы выяснили ранее) главное кодировку указать, а там всё разрулится.
    Отсюда и “проблема” – кодировать данные в JSON нужно вручную, распространнёные библиотечные функции на входе ожидают utf-8.

Мораль сей басни я жду от вас в комментариях.

AJAX и проблемы с кодировкой
Tagged on:     

16 thoughts on “AJAX и проблемы с кодировкой

  • 28.11.2008 at 21:45
    Permalink

    Используйте gzip-сжатие и проблем снова не будет.

  • 28.11.2008 at 23:03
    Permalink

    Имхо не стоят все эти проблемы экономии трафика, да и правильно выше уже про gzip посоветовали. Плюс проблем больше, если у вас база и серверный код тоже в юникоде 🙂

  • 29.11.2008 at 00:21
    Permalink

    IMHO очень сложно получается, много “но” при сомнительных выгодах по трафику, мой выбор UTF-8. А проблему трафика, лучше решать кэшированием или как правильно указал предыдущий комментатор с помощью gzip-сжатия. Например, этот сайт также отображается в кодировке UTF-8, и, не смотря на его явную одно-язычную направленность, автора это почему-то не беспокоит 😉

  • 29.11.2008 at 01:20
    Permalink

    Это конечно отлично – ваша база в unicode, код в unicode – вообще непонятно зачем вы прочитали эту чудо{вищную} заметку – я просил вас на полдороги прекратить чтение и идти поддерживать свой проект дальше…

    Этот сайт (к моему стыду) имеет 2-3 килозахода в месяц и трафик им создаваемый поистине смешон…

    Но если ваш проект имеет 2-3 килохита в минуту “сомнитильная выгода” выливается в килобаксы, что уже, согласитесь, не кисло…

  • 29.11.2008 at 01:58
    Permalink

    Вот у Вас лично выливается лишний трафик в килобаксы хоть где-нибудь? Я, например, сейчас был бы счастлив отдавать со своего сайта _больше_ трафика, потому что иначе я не вписываюсь в бесплатные соотношения. К сожалению или к счастью, но ни на ajax-е ни на html-контенте заметного выигрыша трафика (в любую сторону) получить невозможно. Картинки и прочая медиа покрывает всё это как бык овцу.

    Блин, 2008-ой год на дворе, а вы всё создаёте себе проблемы с кодировками и мужественно их потом преодолеваете…

  • 29.11.2008 at 02:03
    Permalink

    Вот 2008-ой на дворе, а у меня база, и куча приложений, работающих с ней, в кодировке windows-1251 – найти бы мне хотя бы ОДНУ причину выставлять эту базу в вебе через UTF-8…

  • 29.11.2008 at 02:05
    Permalink

    И да, у меня проекты на 90 с гаком процентов текстовые…

  • 29.11.2008 at 02:18
    Permalink

    У меня тоже есть старый сайт в 1251. И даже до сих пор живёт один проект в КОИ-8 (и немаленький, кстати). Но мне и в голову не придёт описывать какие-то кодировочные решения, применённые в них, потому что я прекрасно понимаю, что это всё — технологии прошлого века, и они должны остаться там.

    А Вашу статью сейчас почитают юные кулхацкеры из тех, что измеряют скорость двойных и одинарных кавычек — и пойдут всюду это убожество внедрять, байты экономить.

    Лет пять уже делаю всё исключительно в utf-8 и вообще никогда на клиентском уровне (оговорка потому что в php, сами знаете, тонкости с юникодом есть) никаких проблем не имел. Чего и всем желаю. А то что у меня остались однобайтовые проекты — так это мои проблемы.

  • 29.11.2008 at 09:54
    Permalink

    Ну если юные кулхацкеры, простите, идиоты, то они и без этой “статьи” найдут где нахвататься…
    Я-то пишу не “давайте вернёмся в charset-hell (ц)”, а “не горячитесь перелопачивать всё что нажито непосильным трудом, только потому что в IE кракозябры”, т.к. такие советы считаю полным абсурдом…

  • 29.11.2008 at 17:08
    Permalink

    Тога следует как-то получше сформулировать задачу. Я лично не понял, что в начальных условиях у нас однобайтовый сайт, передалка которого обойдётся себе дороже. Напротив, пассаж:

    Cтандартное решение, которое наперебой советуют все – “используй utf-8 и нет проблем”.

    И советчики правы – проблем действительно не будет.

    Просто трафик увеличится “вдвое”. Те же данные, тот же результат, а трафика “в два раза” больше. Ага?

    Что вы там говорите насчёт порошка?!?

    Если вам этот фактор кажется мало***щим, то на этом чтение надо прекратить и начать переделывать свой проект на использование UTF-X

    лично я расшифровал как «вы конечно можете делать проекты на utf, если вам не жалко трафика, а вот если вы думаете о юзере…»

  • 29.11.2008 at 17:08
    Permalink

    Прошу прощения за опечатки.

  • 29.11.2008 at 17:51
    Permalink

    Вставил небольшой update. Спасибо за участие 🙂

  • 25.10.2009 at 06:51
    Permalink

    интресно интересно…
    однако
    //Проверяем все ли переменные на месте
    if (!(isset($_GET[‘name’]) &&
    isset($_GET[‘telefon’]) &&
    isset($_GET[‘interes’]) &&
    isset($_GET[‘time’]))) {die(‘Ошибка в данных!’);}
    //Строим тело и загаловки
    $message .= ‘Имя: ‘.$name.”;
    $message .= ‘Номер телефона: ‘.$telefon.”;
    $message .= ‘Что интересует: ‘.$interes.”;
    $message .= ‘Желаемое время звонка: ‘.$time.”;
    $message .= ‘Дата подачи заявки: ‘.$now;
    echo ‘В результате тут будет шляпа которая не работает в Opera UTF ‘
    приходится делать перекодировку ..поэтому все
    зависит от средств реализации..
    вообщем UTF круто..но не настолько чтобы его везде сувать….и не в многозычные системы вообще смысла нету его ставить…лишняя нагрузка работы с двухбайтными символами= эквивалентная 20%…

  • 25.10.2009 at 09:17
    Permalink

    Конечно глупо переспрашивать, но тем не менее всё-таки любопытно что вы хотели сказать этой ахи^W хм… этим кодом? Что у вас там не работает? Где? При каких обстоятельствах? Как вообще всё это соотносится с описанной темой?

  • 13.12.2010 at 20:48
    Permalink

    Лучше бы не читала. Переделала. Козяблики ушли, отвалился поиск. Жаль до коментариев дошла поздно.Целый день коту под хвост. Лучше бы с козябликами сидела

  • 14.12.2010 at 23:02
    Permalink

    Ума нет – считай калека.

Leave a Reply