AJAX и проблемы с кодировками.
Главная » Блог » AJAX и проблемы с кодировками.Очень часто разработчики в тех или иных ситуациях сталкиваются с проблемами, связанными с кодировками. Особенно те, кто работает в кодировке windows-1251. Сегодня хотел рассмотреть эту проблему, посмотреть разные примеры и возможные решения.
AJAX
AJAX (Asynchronous Javascript and XML, асинхронный Javascript и XML) очень тесно вошел в обиходе, и сложно представить себе современный сайт без использования этой технологии. По сути, аякс это фоновый обмен данными, что позволяет получать данные без перезагрузки страницы. Различные "живые поиски", регистрации, формы обратной связи и т.д.
Через AJAX мы можем передавать данные методом POST и GET. Давайте разберемся, какие могут быть проблемы в передачи этих данных.
Начем с GET.
Когда мы передаем данные через GET – это значит мы посылает скрипту URL, в котором русский текст должен быть закодирован, в определенной последовательности. Называется она escape-последовательностью.
Например:
ajax.php?query=%D1%80%D1%83%D1%81%D1%81%D0%BA%D0%B8%D0%B9+%D1%82%D0%B5%D0%BA%D1%81%D1%82
В этом GET запросе, query передает фразу "русский текст". Но escape-последовательности отличаются друг от друга, в зависимости от используемой кодировки. Для того что бы перевести русский текст в последовательность, W3C рекомендует использовать функцию "encodeURIComponent()", которая автоматически переводит текст в utf-8 и создает escape-последовательность. Поэтому при передаче текста через Jquery, Prototype, и другие фреймворки, на выходе мы получаем текст в UTF-8 кодировке. Если вы работаете в кодировке Windows-1251, то придется вначале текст перевести из utf-8 в Windows-1251 ( это можно сделать через iconv, например: $_GET['query'] = iconv('utf-8', 'Windows-1251', $_GET['query'])).
С теорией закончили, теперь давайте рассмотрим примеры. Есть один интересный нюанс, который я обнаружил. Я работал с фреймворком Jquery, сайт работает в utf-8, обработчик ajax запросов работает в utf-8, база данных работает в utf-8, короче все узлы сайта построены в этой кодировке. Рассчитывая на то, что Jquery посылает запрос через encodeURIComponent(), я его не стал использовать. Да и в принципе никаких проблем не было, пока не стали приходить запросы с "каказябрами", при том что Firefox, Chrome и Opera корректно присылали запросы в utf-8, но вот Internet Explorer, как самый выдающийся браузер, умудрялся присылать запросы в windows-1251.
Я решил провести тест, и разобраться при каких ситуациях IE посылает неверную кодировку.
Есть 2 скрипта:
$.get("ajax.php", { "query": "Русский текст" },function(data){ alert(data) })
Результат:
$.ajax({ dataType: 'html', type: "GET", url: "ajax.php", data: 'query=Русский текст', success: function(data){ alert(data); } });
Результат:
Так вот, проверив оба, я выяснил что в $.ajax IE посылает не UTF-8, а Windows-1251. Решение этой проблемы – добавить encodeURIComponent() и все будет хорошо.
$.ajax({ dataType: 'html', type: "GET", url: "ajax.php", data: 'query='+encodeURIComponent('Русский текст'), success: function(data){ alert(data) } });
Резальтат:
Хорошо, с GET запросами разобрались.
Теперь рассмотрим коротко POST.
В отличие от GET запросов, в POST передается Content-type, который сообщает серверному скрипту информацию, о том с какими данными он работает и возможность указания кодировки. Например, в Jquery по умолчанию AJAX передает "application/x-www-form-urlencoded; charset=UTF-8", но даже если вы укажите “text/html; charset=windows-1251”, то данные приходящие будут в utf-8, так как при передачи данных, Jquery формирует escape-последовательность, функцией, о которой писалось выше.
Но это не так страшно, потому что у нас есть всегда возможность перевести кодировку и уже работать с данными. При этом отдавать результаты мы можем в нашей любимой кодировке, главное не забывайте ставить заголовок, с указанием кодировки, если вдруг вы обратно получаете "каказябры".
Например:
header('Content-type: text/html; charset=windows-1251');
или:
header('Content-type: text/html; charset=utf-8');
Вывод: для того что бы не было проблем с кодировками, при передачи данных через AJAX, нужно использовать encodeURIComponent(). Если ваш серверный скрипт, который принимает запросы, работает в другой кодировке, отличной от utf-8, то надо пользоваться php функцией iconv и устанавливать заголовок header.