Пользователь
0,0
рейтинг
17 декабря 2007 в 19:59

Разработка → Разберемся раз и навсегда: AJAX, «кириллические символы», кодировки, prototype.js, jQuery, JsHttpRequest

AJAX, — это технология. Одной из часто используемых техник этой технологии является
посылка запросов при помощи объекта класса XMLHttpRequest.


Как же посылать и принимать AJAX запросы в нужной нам кодировке, нужно ли использовать однобайтовые кодировки или не обойтись без UTF-8. На все эти вопросы раз и навсегда ответит эта статья.



Кстати, перепечатка с моего.

И ещё, классов-то, конечно, в JavaScript нет, но для удобства будем пользоваться такой терминологией.

В документации на XMLHttpRequest сказано, что браузер должен поддерживать следующие типы
HTTP-запросов: GET, POST, HEAD, PUT, DELETE, OPTIONS.

На сегодняшний день джаваскриптом через объект класса XMLHttpRequest можно отправить
только запросы типа GET и POST.

Итак, рассмотрим 2 этих запроса:

1. Запрос типа GET:

Вся информация скрипту на сервере может передаваться только через URL и через заголовки.

Например,

GET moy-rebenok/ajax.php?f=324
Host: moy-rebenok
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; ru; rv:1.8.1.11) Gecko/20071127
Firefox/2.0.0.11
Accept:
text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/pn
g,*/*;q=0.5
Accept-Language: ru-ru,ru;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip,deflate
Accept-Charset: windows-1251,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Referer: moy-rebenok/ajax.html

На сервере, в ajax.php можно будет использовать конструкцию
$_GET['f'], чтобы получить значение переменной f.

Почему встает проблема с русскими буквами? Потому что, как вы знаете, русские буквы в URL использовать нельзя, их необходимо как-то передать при помощи доступных латинских букв, цифр и знаков, допустимых в URL после знака '?'.

Люди договорились, что будут делать это при помощи escape-последовательностей.

escape последовательность слова «привет» в кодировке windows-1251:
%EF%F0%E8%E2%E5%F2

escape последовательность слова «привет» в кодировке UTF-8:
%D0%BF%D1%80%D0%B8%D0%B2%D0%B5%D1%82

escape последовательность слова «привет» в кодировке KOI8-R:
%CE%CF%D5%C1%C5%D0

(Знак '%', потом код символа).

Таким образом передать русские буквы можно, например, так:

GET moy-rebenok/ajax.php?f=%EF%F0%E8%E2%E5%F2
Host:…

или так:

GET moy-rebenok/ajax.php?f=%D0%BF%D1%80%D0%B8%D0%B2%D0%B5%D1%82
Host:…

Никто вас в этом не ограничивает.

Кстати, для GET запроса не нужно указывать заголовок Content-Type.
Т.к. никакого контента нет. Есть только запрос по определенному адресу.
Все переменные на сервер передаются через URL.

Как же смастерить необходимую escape последовательность в нужной кодировке?

Мастерить можно хоть руками, хоть как, но естественно в JavaScript.
Опять же, никто вас не ограничивает.

Но для удобства обычно используют одну из 3 функций, которые уже определены в JavaScript:

а) escape()
б) encodeURI()
в) encodeURIComponent()

По порядку:

а) escape()

Латинские буквы, цифры, символы @*/+. оставляет как есть, всё остальное кодирует так:
%xx, либо так: %uxxxx.
Причем, xxxx во втором случае, — это код символа не в UTF-8, а в Unicode

(Разница между Unicode и UTF-8).

Использовать эту функцию не надо, т.к. результат выполнения зависит от браузера, функция не является стандартизированной W3C, возникла в лихие 90-е.

К тому же, как-то нормально (по крайней мере, быстро) обработать строку в таком винигретчатом формате на сервере сложно.

Функцию escape() использует библиотека нашего соотечественника JsHttpRequest.
Не потому что библиотека плохая, а потому что создана для работы со всеми браузерами
(в том числе и с самыми древними).

б) encodeURI()

Латинские буквы, цифры, символы !@#$&*()=:/;?+'. оставляет как есть, всё остальное
кодирует
escape-последовательностями в кодировке UTF-8.

в) encodeURIComponent():

Латинские буквы, цифры, символы !*()'. оставляет как есть, всё остальное кодирует
escape-последовательностями в кодировке UTF-8.
Одобрено W3C.

Используется jQuery, prototype.js при запросе методом GET.

Возможно вы слышали от кого-то: «XMLHttpRequest работает только с UTF-8».
Теперь знаете, что это не совсем правда.

Когда используется GET-запрос, то кодировка переданных данных вообще нигде не прописывается(!).
Ещё раз повторю, 'Content-type', в котором мы можем указать charset
не используется в GET запросах.

Но, т.к. в JavaScript есть 2 удобные функции для перевода любой строки в строку с escape-последовательностями в UTF-8, то все их используют, и работают с UTF-8.

Именно поэтому в jQuery даже нельзя никак указать charset при отправке запроса.
Именно поэтому в Prototype.js, даже когда указываешь encoding='windows-1251', и используешь GET запрос, то передается всё равно UTF-8.

Просто потому что в кодах этих библиотек используется функция encodeURIComponent().

Что ж. В этом нет совершенно ничего плохого. Всё, что надо сделать, чтобы теперь работать
в PHP в
нормальной кодировке использовать iconv:

$f = iconv('UTF-8', 'windows-1251', $_GET['f']);

Кстати, мы можем это сделать именно потому, что $_GET работает так, что он понимает
escape-последовательности. Спасибо создателям PHP.

Т.е. когда приходит GET запрос PHP смотрит на URL, создает для нас массив $_GET, а мы
уже с ним
что хотим, то и делаем. Но это вроде понятно должно быть.

2) POST-запросы.

Здесь уже всё интереснее.

Вот приходит это запрос на сервер. Обработчик PHP смотрит на Content-type, и в зависимости от него заполняет массив $_POST и/или переменную $HTTP_RAW_POST_DATA.

$_POST он заполняет в том случае, когда в Content-type указано multipart/form-data или
x-www-form-urlencoded.

Что-же это за Content-type такой?
А контент-тайп это очень удобный. Он позволяет передать php скрипту несколько переменных.

Что по сути такое POST запрос?
Это заголовки, а за ними контент. Контент вообще произвольный. Т.е. просто байты, байты, байты.

Но ведь из JavaScript обычно требуется передать не просто байты, байты, байты, а несколько пар ключ=значение, ключ=значение,…
Как в GET запросе.

Вот люди и договорились о таком удобном типе, как x-www-form-urlencoded
Для того, чтобы передать f=123 и gt=null необходимо передать контент:

f=123&gt=null

Знакомо неправда ли? Конечно знакомо, и тип не зря называется x-www-form-urlencoded.
Всё то же самое, что и при GET запросе.

И как же формируется контент в библиотеках jQuery и prototype.js?

Верно, при помощи всё той же функции encodeURIComponent(), а значит и escape-последовательности будут в кодировке UTF-8. (Независимо от того, что в prototype.js вы установите encoding).

Всё. Осталась ещё одна возможность. Ведь можно передавать не x-www-form-urlencoded (т.е. не параметры), а обычный текстовый или бинарный контент, который потом можно будет прочитать через $HTTP_RAW_POST_DATA.

Для этого устанавливаем Content-type text/xml или application/octet-stream, там же устанавливаем charset=«windows-1251».

Засовываем в функцию send() строку нужной кодировки. (Prototype.js оборачивает этот вызов конструкцией new Ajax.Request(...)).

И что потом… А он (объект класса XMLHttpRequest) переводит эту строку в UTF-8, в какой бы кодировке она не была. Так написано в документации W3C. И он реально это делает.

Выводы:

1. Напрямую через XMLHttpRequest можно передавать только строки в кодировке UTF-8.

2. Можно передавать строки как бы «в любых других кодировках», если нелатинские символы
при этом за-escape-ены.

3. В JavaScript существует 3 функции, которые escape-ят нелатинские символы:
escape(), encodeURI() и encodeURIComponent().

Первая переводит в кривой Unicode. Вторые две в UTF-8.

Можно написать свои функции, которые будут генерировать escape-последовательности любой кодировки. Можно, но не нужно. Т.к. наоборот надо радоваться, что есть такие вот функции, которые переводят текст любой кодировки в UTF-8. Это черезвычайно прекрасный факт. Схема при которой все xhtml страницы работают на windows-1251, ajax с сервера клиенту кидает windows-1251, а ajax с клиента серверу кидает UTF-8 абсолютна приемлема и используется на большинстве ресурсов.

Просто не надо забывать использовать iconv как было описано ниже. А для того, чтобы сервер отдавал яваскрипту JSON (или что там у вас) в правильной кодировке (т.е. в такой же кодировке, в которой отдаются все xhtml страницы) просто в начале вашего ajax.php пропишите заголовок:

header('Content-type: text/html; charset=windows-1251');

И всё будет ок.

На последок немного субъективного мнения:

Используйте jQuery, любите людей, дарите подарки.
Майк Зимин @mihazimin
карма
20,0
рейтинг 0,0
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое Разработка

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

  • 0
    Про habracut - забыли?
    • 0
      да, спасибо, уже поправил.
  • 0
    День JS на хабре? :)
    На все эти вопросы раз и навсегда ответит эта статья.

    Не сказать, чтобы она ответила на все вопросы.

    2. Можно передавать строки как бы "в любых других кодировках", если нелатинские символы
    при этом за-escape-ены.

    Как из недр JS можно передать не unicode-кодировку?

    Схема при которой все xhtml страницы работают на windows-1251, ajax с сервера клиенту кидает windows-1251, а ajax с клиента серверу кидает UTF-8 абсолютна приемлема и используется на большинстве ресурсов.

    Но еще более приемлима схема, когда везде UTF :) Тогда и iconv никакой не нужен и в других областях (не ajax) проблем меньше.
    • 0
      и иконм и в других областях и страници вдвое тяжелее....
    • 0
      +1, у самого сайт, хоть и не без труда, переведён на UTF-8. Запары бывают только с теми функциями что не понимают UTF, тогда юзаю iconv. Но такое встречается редко.
  • +8
    Кодировки вроде windows-1251 — архаизм.
    Зачем каждый раз iconv дёргать, зачем эти трансляции?
    UTF-8 наше всё. И если идти в ногу со временем, эта статья бы не появилась.
    • 0
      Ребята, этот топик как раз о том как делает большинство профессиональных разработчиков в России сейчас.

      Столкнувшись с тем, что, по большому счету, AJAX запрос всегда отправляет UTF-8 молодые разработчики приходят к мнению о том, что нужно и страницы непременно отправлять в нём. Что, в принципе, не является панацеей. И не всегда оптимально сказывается на производительности.

      Зачем всё делать на UTF-8 когда страницы содержат только русские и латинские буквы? Сортировки в UTF-8 могут проходить в несколько раз медленнее, количество контента загруженного на страницы увеличивается в 2 раза.

      И почему habrahabr.ru и др. не используют UTF-8 как основную кодировку, при этом во всю отправляя AJAX запросы в ней?

      Ответ прост: это удобно и эффективно.
      • НЛО прилетело и опубликовало эту надпись здесь
      • +3
        Зачем всё делать на UTF-8 когда страницы содержат только русские и латинские буквы?

        А почему бы и не в UTF?
        Сортировки в UTF-8 могут проходить в несколько раз медленнее

        Какие сортировки? В базе? Так все нормальные базы внутри в UTF. Если же вы работаете не в UTF, то это означает только, что на входе и выходе базы будет происходить перекодировка, что будет есть ресурсы, за которые вы так волнуетесь. Добавьте сюда бесконечные SET NAMES при запросах и множество тем на форумах: "Ах, почему у меня сплошные вопросики выводятся".
        количество контента загруженного на страницы увеличивается в 2 раза

        Количество контента будет = верстка + английский контент + русский * 2
        По сравнению с общим объемом, включая картинки, прибавка для современных сетей ничтожна. Используйте gzip-сжатие и вообще будет стремится к нулю
      • НЛО прилетело и опубликовало эту надпись здесь
        • НЛО прилетело и опубликовало эту надпись здесь
  • 0
    а можно идиоту пояснить — зачем использовать 1251 страницу (Или любую другую не utf-8) если всё остальное идёт в utf-8?!!!!!!
    • 0
      Видимо потому что все привыкли к 1251, всё работает и сверстано в 1251 (еще в конце 90х), а теперь бедному программисту приказали быстро навешать на всё это модных фенечек :)
      • 0
        что-то я не видел таких проектов. чтобы аякс и свёрстано в конце 90х... да ещё и в 1251...
        • 0
          Сейчас вы находитесь на сайте, который отдаёт страницы отнюдь не в UTF-8, при этом вполне сносно AJAX-запросы отправляет, естественно, в UTF-8.
          • 0
            я знаю. просто вы привели аргумент что де в конце 90х наделали супер-дизайнов. что теперь их переделывать нельзя, а можно лишь добавить ajax-перделок. как-то мне сразу в это не поверилось.

            что касается хабры — я так и не могу понять для чего это сделано.
            • 0
              не, это не я привел. Это стебался кто-то.
              • 0
                да. извиняюсь, это был gro.
            • +1
              Ну vkontakte.ru, moikrug.ru, market.yandex.ru всё таки тоже работают на windows-1251 будучи при этом глубоко эйджексовыми.

              Для меня это совершенно приемлемо, т.к. всё же (я уже писал где-то) скорость работы с БД на однобайтовой кодировке превышает скорость работы с базой на UTF-8.
              Да и xhtml страницы грузятся быстрее.

              Буду рад от вас услышать, почему вы считаете, что лучше всё же везде где есть русские буквы использовать UTF-8.
              • 0
                я не агитировал за что-либо. я как раз интересовался что движет людьми при выборе 1251.
                • 0
                  А, понятно. На самом деле пробовал я один раз на UTF-8 поднять сайт (потому что как раз решил заюзать там AJAX), но оказалось, что не так всё с этим UTF-8 гладко как хотелось бы. Вообще почему то в реальных разработках серверные программисты на нем не любят работать.

                  Вот, например, здесь где-то есть комментарий, что PHP не поддерживает нативно UTF-8.

                  Т.е. технологии пока всё таки не дошли до его всестороннего использования, поэтому когда его можно не использовать, я его не использую.

                  Хотя года через 2-3, возможно, действительно все будут на нем делать.
                  • 0
                    Надо делать сеичас. UTF-8 сегодня держит всё даже винда вистовская. А зачем вам поддержка найтив РНР - юзайте mb_string!
                    Да 2+ байта накладно, да на 20% дольше обработка. Но надо стремиться к какому-то стандарту!
                  • НЛО прилетело и опубликовало эту надпись здесь
                    • 0
                      XML+XSLT в PHP работают с любыми кодировками, потому что под ними лежит libxml + libxslt. Другое дело, что если работать с XML через DOM в PHP, то надо данные ручками конвертировать в UTF-8.
                      • НЛО прилетело и опубликовало эту надпись здесь
              • 0
                Не везде, где есть русские буквы, а везде, где есть мультиязычность.
                Unicode является универсальной кодировкой. Он позволяет на одной странице общаться китайцу и русскому. И немец еще будет комментарии на родном языке оставлять (они же все друг друга понимают, да?)
                • 0
                  Да, абсолютно с вами согласен. Wikipedia можно было сделать только на UTF-8.

                  Но я специально написал "русские буквы". Если вы делаете сайт на котором не предполагается многоязычности (т.е. только латиница и русский), то зачем использовать UTF-8?
                  • 0
                    Вчера не предполагалось, а завтра придет начальник... или еще какая-нибудь ерунда в этом же духе произойдет.
              • 0
                Ага... вот почему у меня на этих сайтах в Конкероре после ajax-запроса половина страницы окракозябливается.
              • 0
                Аргумент один: отсутствие необходимости следить за кодировкой. Там где критична скорость выполнения - то есть на сайтах с большой посещаемостью - лучше использовать гибридный вариант. На маленьких я лично использую UTF-8 и на клиенте и на сервере, но оставляю лазейку чтоб в случае чего без проблем мигрировать на этот самый гибридный вариант.

                В конце концов, время сейчас такое, когда простота приносится в жертву скорости выполнения. Так что переход к ресурсоёмким, но простым технологиям это ход в духе времени.
                • –1
                  Wikipedia — маленький сайт?
                  Google — маленький сайт?
                  ...
                  • –1
                    Нихрена не понял, что Вы хотели сказать. Если они используют UTF-8 - здорово, это шаг к упрощению, тем более, если учесть, что они могут позволить себе наращивать мощности серверов до бесконечности.

                    Я написал "Я лично". У меня таких мощностей нет, иногда приходится изголяться. И - я написал "Оставляю лазейку для перехода на UTF-8".

                    Кроме того, я не очень представляю как гугл обошёлся бы искомой 1251 на клиенте, если учесть всё многообразие его многоязычных версий.

                    Вообще, чтоб говорить сколь-нибудь аргументированно на тему гибридный вариант vs UTF-8 нужно иметь какие-то осмысленные данные по потерям производительности на UTF-8. Понятно, что UTF работает медленно, но насколько и можно ли в каждом конкретном случае пренебрегать потерями - не ясно.
    • +1
      Потому что иногда 1 байт лучше UTF-8. Обработка текстов, например, в 1-байтовых кодировках проходит в разы быстрее.
      • 0
        Show me the code! В смысле результаты бенчей.
        • 0
          Проводили бенчмарки на SAP с СУБД Oracle.
          Windows-1252 vs UTF-8. По скорости обработки UTF-8 отстаёт на 20%
          • 0
            Железо дешевле, чем труд программистов! 20% - не тот прирост, из-за которого надо сделать всё через жопу. Особенно, если потом придётся переделывать.
            Я поражаюсь этой логике, автор статьи предлагает, буквально, удалять гланды электродом через задний проход - авторы js библиотек оторвали кодироки, и правильно сделали - чтобы проблем было меньше.. нет, ведь найдут способ перекодировать туда-сюда, чтоб самим себе геморой создать! А потом - начинается - тут перегодировать, там в UTF отдать.. Тот же хабр - RSS отдаёт в UTF - почему? Да потому что это тру, и никакой feedburner бомжовые cp1251 и koi8 жрать не будет, и правильно делает! И так везде!
            Любят же люди себе жизнь усложнять..
  • 0
    ничего нового не узнал. новичкам будет полезно.
  • +1
    Проблема надуманна.
    Те, кому еще надо поддерживать зоопарк кодировок и так знают, что надо делать.
    Все остальные давно используют utf8 и не заморачиваются.
    • 0
      Бр. А кто все остальные то? Назовите мне известные успешные сайты, которые используют только русский язык и при этом всё отдают в UTF-8.
      • 0
        Результаты поиска на Яндексе отдаеются в utf-8.
  • 0
    А давно в JavaScript объектов нет?
    • +3
      В JavaScript нет классов. А объекты там ещё как есть.
  • +1
    Мне, право, неловко, но всё же кириллические. ;-)
    • 0
      спасибо, исправил
  • +2
    классов[дефис]то, конечно, в JavaScript нет
  • 0
    Да можно, да, вполне рационально...

    НО: хрен я буду использовать кириллицу, пока в том же php не будет нормальной поддержки юникода (пока она не будет native, как планируется в php6).
    • 0
      А что вы понимаете под нормальной поддержкой?
      Если уже вы передали браузеру Content-Type: text/html; charset=utf-8; то отвечать но будет вам ни чем иным как utf-8 и это дело можно с лёгкостью обработать mb_string'ом. и переконвертировать в куда угодно.
      • 0
        Эм, Вы понимаете какая тут штука, mbstring - расширение, это раз.
        Я недавно закончил проект, разрабатывался он полностью и везде на utf8, именно по этому поводу есть ряд замечаний. Начну с того, что проект был небольшой, но столкнулся я со следующими проблемами:

        - preg_match (это не mbstring), поддерживает utf, но не полностью, и я как раз попал в этот вот кусочек "неподдерживаемости".
        - само расширение не позволяет работать с регулярками, кроме как с posix-совместимыми, которые жутко как медленны.
        - есть строковые функции (нативные), которые utf не поддерживают вообще, и в mbstring их, соответственно нет. (точно не скажу, но по-моему strstr/stristr).

        Нормальная поддержка - дефолтный utf8 для всего, что делается на этом языке + нехилое расширение для работы со всеми возможными кодировками (не какая-то перезагрузка в существующем расширении, а что-то более удобное).
        • 0
          Насколько я знаю, если текст в UTF-8 и паттерн тоже в UTF-8, то достаточно добавить модификатор u и всё будет нормально работать.
          • 0
            У меня была проблема следующего плана:
            preg_replace/str_ireplace/mb_eregi_replace использовал, чтобы произвести замену "ПрИмЕрНо ВоТ тАкОгО тЕксТа" на "примерно вот такой" с тегами, все в utf, не получилось.
            • 0
              а mb_strtolower() перестал работать?
              • 0
                Не знаю, но в нем спасения не было.

                В общем, толку, что мы тут рассуждаем как тривиальные вещи делать через одно место? Меня не очень устраивает вариант как минимум поиска решения по тому вопросу, который вообще не требует задумываться.
  • +2
    Здравствуйте ХабраЛюди! Приношу свои извинения что пишу комментарий не по теме. Но мне не обойтись без вашей помощи. Я хочу сделать свой блог. Зарегистрировался, вроде страница существует http://alex93.habrahabr.ru/ но когда нажимаю написать мне выходит окно с рассказами про карму и тд. Помогите мне.
    • 0
      Всё, в личном блоге можешь писать.
  • 0
    У меня всегда возникала проблема с получением данных от php скрипты, данные он возвращает в windows-1251, основной скрипт - win1251, но приходят кракозябли ;)
    • 0
      А вот такая штука стоит:
      header('Content-type: text/html; charset=windows-1251');
      ?
  • НЛО прилетело и опубликовало эту надпись здесь
    • 0
      Да, решение похоже на котеровский JsHttpRequest. Интересно кто был первый? :-)
      • НЛО прилетело и опубликовало эту надпись здесь
    • 0
      Жестоко! Работает только с кирилицей? :-)
      • НЛО прилетело и опубликовало эту надпись здесь
        • 0
          Не кошерно. Допустим это ввод пользователя (комментарий, как на хабре). Фраза на немецком языке с умляутами будет отваливаться. Что собственно и видно на примере хабра:
          фраза "Allgemeine Information uber das Projekt" отвалится, только из-за одной буквы "u"(умляут). Вот что мы видим в итоге: "Allgemeine Information
          • НЛО прилетело и опубликовало эту надпись здесь
  • НЛО прилетело и опубликовало эту надпись здесь
  • +1
    > На все эти вопросы раз и навсегда ответит эта статья.

    Спасибо, о Мудрейший :-)

    > encodeURI()
    > . . .
    > Одобрено W3C.

    http://www.google.com/search?q=encodeURI…

    > Кстати, мы можем это сделать именно потому, что $_GET работает так, что он понимает escape-последовательности. Спасибо создателям PHP.

    [смайлик, безнадёжно бьющий себя по лбу]
    Нет, я всё понимаю, но...
    [смайлик, безнадёжно бьющий себя по лбу]

    > есть такие вот функции, которые переводят текст любой кодировки в UTF-8.

    Не любой кодировки, а Unicode. Javascript внутри весь unicode'ный.

    > в начале вашего ajax.php пропишите заголовок:
    > header('Content-type: text/html; charset=windows-1251');
    > И всё будет ок.

    И ведь пропишут.
    • +1
      О ещё более мудрейший!

      1. Да, лоханулся, сейчас исправлю :-)

      2. Да я вообще то на php не программирую. На джабескрипт только. Так что тут поспорить не получиться серьёзно. Но всё ж, что не верно-то написано по вашему?

      3. Не любой кодировки, а Unicode. Javascript внутри весь unicode'ный.

      Т.е. строка в JavaScript всегда храниться в юникод представлении, однако сам скрипт (script) имеет кодировку и когда происходит вывод в DOM, то юникод преобразуется в эту кодировку?
      • 0
        2. Да вроде всё верно, просто это преобразование — не бог весть что, чтобы за него отдельно Расмуса благодарить. Да, если уж кого и благодарить — то лично его, ибо наверняка это уже в PHP/FI было.

        3. Не знаю, как именно она хранится (может, это от браузера даже зависит), но с точки зрения языка — все строки в Юникоде. И, если в момент загрузки скрипта браузер верно знает его кодировку, то я даже не уверен, что эту кодировку потом в скрипте можно узнать достоверно. Оставаясь в рамках стандартов, по крайней мере.
  • +3
    эээ юзайте utf-8 везде!
    • НЛО прилетело и опубликовало эту надпись здесь
    • 0
      Ваши аргументы?
      • НЛО прилетело и опубликовало эту надпись здесь
        • НЛО прилетело и опубликовало эту надпись здесь
  • +1
    большое спасибо за статью :) В принципе, нечто подобное я раньше и пытался делать, но потом подумал и понял - а почему бы просто не использовать utf-8? Ведь в нем гораздо больше плюсов, да и он все больше и больше встречается на всех ресурсах :)

    PS Использую и люблю jQuery, люблю людей и зверей :), дарю, но не получаю подарки :(.
  • 0
    > Используйте jQuery, любите людей, дарите подарки.

    ну вот зачем было про jQuery?

    я совсем не против этой библиотеки, но мне (и 70% javascript-разработчиков) больше нравится prototype.js

    не дразните гусей : )
    • +1
      производительность
      • 0
        время выполнения $('#id') = 600ms вы называете высокой производительностью? : ) оно за 1ms должно отрабатывать! : )

        согласен, в последней версии они это исправили, но на репутации все равно несмываемое пятно ; )

        кроме того, даже в последней версии нету у jQuery однозначного превосходства
        • 0
          600? ого, это где вы такие страшные цифры берете, даже на ранних версиях я такого не наблюдал.
          А превосходство есть, и все кто перешел с прототипа на jQuery скажут сразу - размер!
          • 0
            в их блоге и беру

            $(”#id”) Improvements
            jQuery 1.1.3 — 651ms
            jQuery 1.1.4 — 70ms

            размер означает отсутствие некоей функциональности. Можно вообще не использовать библиотек, и ничего не нужно будет скачивать :р

            в общем, факт я предоставил, в холиворе участвовать не буду
        • –1
          mootools: быстрее, меньше, сильнее!
          Не дразните гусей)
          • 0
            ага, давайте ещё все остальные либы перечислим...
    • 0
      Не знаю, как с jQuery, но при использовании prototype у меня возникли проблемы с конструкцией for(var k in ar){}, где ar-массив. В массиве появляются какие-то посторонние (прототайповские) строковые ключи. Предполагается использование только численных ключей?
      • 0
        это было спорное решение в старых версиях, именно ему библиотека обязана названием, как я понимаю

        сейчас с этим все хорошо

        впрочем, даже известный идеолог яваскрипта Крокфорд, считает цикл for in реализованным неудачно в самом яваскрипте
      • 0
        вместо for(var k in ar){} можно использовать конструкцию
        ar.each(function(k){
        // где k и будет элементом массива
        });
    • 0
      Знаете почему я перешел с prototype на jQuery где-то 3 месяца назад?

      1. Потому написание плагинов к нему стандартизированно. Если вы когда-нибудь работали со script.aculo.us, то знаете как сложно исправить код в чужом плагине и то, что все пишут плагины с какими в голову придет интерфейсами.

      2. Я хочу писать на JavaScript не как на C++ и Ruby, а как на JavaScript: используя все его преимущества.
      • 0
        1) я работал и работаю со скриптакулосом, и никаких проблем не ощущаю. И вообще криворукость кодеров очень слабо зависит от библиотеки.

        2) я пока что не буду этот пункт называть нелепым : ) Вначале объясните, что имеете в виду, а то такое обвинение в адрес прототайпа я встречаю первый раз.
        • 0
          Скажите вы пробовали писать на jQuery или только читали и вам сразу не понравилось?

          1) "криворукость кодеров" надо воспринимать просто как составляющую контекста работы. Люди не идеальны. В jQuery стандартизировано не только написание плагинов, но и документации к ним.

          2) Вы наверняка знаете, что prototype.js сейчас, - уже практически часть ROR. А все конструкции, - Hash, добавки к Array и т.д. - это напрямую взяты из Core Ruby, как кстати и слово initialize.
          Да, это всё круто, когда на сервере лежит Ruby, убыстряет разработку. (Правда).

          Я совсем не против Ruby, но если на backendе лежит php, то я не вижу объективных причин его использовать.
          • 0
            я видел примеры ее использования, и мне они не понравились. Я не хочу писать такой код.

            1) html тоже стандартизован, и это не сильно помогает ; ) А приобретая в качестве, всегда теряешь в количестве. Можете не возражать, я в этом уверен :р

            2) ощутимая часть этих конструкций мне хорошо пригождается в самом яваскрипте, поэтому мне все равно, откуда они взяты. И вы не сказали про преимущества js, с которых и началось это обсуждение. Каким образом прототайп не позволяет вам их использовать?

            у меня на бэкэнде именно php, и я с большим удовольствием использую прототайп
            • 0
              атри может хваттит с пеной у рта доказыавать свою правоту, пользуйся любой библиотекой, хоть им.Ленина. и не нужно было минусовать мою карму, только из-за того что я выразил свое мение.
              • 0
                я не доказываю свою правоту, а реагирую на попытки доказать, что jQuery однозначно лучше Prototype.js. И делаю это не с пеной у рта, а спокойно и цивилизованно.

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

                при чем тут карма, я не понял
          • 0
            Пробовали разные. А работаем с jQuery. Очень довольны. =)
  • 0
    На сегодняшний день джаваскриптом через объект класса XMLHttpRequest можно отправить не только запросы типа GET и POST, но и PUT, DELETE, HEAD.
    • 0
      В каких браузерах возможно отправить XMLHttpRequest типа PUT, DELETE и HEAD?
      • 0
        ff, ie, opera, safari (win)
        проверял в последних версиях (ff - 2.x >, ie - 6.x >, opera 9.x >, safari - не помню какая под вин последняя, уверен, что на маках тоже работает и в более ранних версиях указанных браузерах тоже)
        По сути, способ передачи данных у методов не очень отличаются от GET и POST
        • 0
          Хм, действительно работает. Спасибо, сейчас внесу изменения в статью. Я вот не проверил, а поверил документации и коду prototype.js:

          if (!['get', 'post'].include(this.method)) {
          // simulate other verbs over post
          params['_method'] = this.method;
          this.method = 'post';
          }

          причем поменять это поведение никакими параметрами поменять невозможно.
      • 0
        Лучше вопрос, а какие серверы их обрабатывают? :)
  • 0
    Ну вот. Недавно столкнулся с похожей проблемой. Сойт в вин 1251. Решил её совершенно НЕ так как описывает автор. БОЛЕЕ ТОГО. Никакого ICONV НЕ ИСПОЛЬЗУЮ.
    Может быть кто то объяснит как мне это удалось? Я тупо подобрал) Итак:
    Дано сайт в кодировке 1251. Задача - встроить гугл мэпс.
    Решение:
    Параметры карты передаю в БД тупо:
    urlparams = "?mode="+"save"+"&name=" + name + "&hello=" + hello + "&sex=" + sex + "&lat=" + lat + "&lng=" + lng + "&baseurl=" + baseurl + "&currurl=" + currurl;
    urlinsert = baseurl+"/user/maps_insert.php"+urlparams;
    new Ajax(urlinsert, {method: "post"}).request(); (мутулз)

    В БД "крякозяблики", при отображении использую функцию UNESCAPE:
    for (var i = 0; i < markers.length; i++) {
    var name = unescape(markers[i].getAttribute("name"));
    Никакого iconv, всё работает (www.msexy.ru). Что я сделал не так??
    • 0
      Вы не обрабатываете данные. Вы их получаете, тупо, как вы выражаетесь, передаете в БД и так же тупо выдаете. Поэтому фраза про "Сойт в вин 1251" к делу не относится, он может быть хоть в DOS.
      • 0
        Сойт=Сайт. Насчет не обрабатываю - не совсем понял. Была проблема - русские буквы из БД выводились кракозябликами) Использование функции unescape - решило проблему кракозябликов. iconv не понадобился (у меня его нет на хостинге). Вот собственно и всё. Просто вроде как в статье утверждается что без iconv не обойтись..
        Извините - раз в 5 минут коммент, поэтому тут про атаки спрошу.
        Если тупо искать строки select\insert\delete в параметрах и отбрасывать параметры если они там вдруг появились - это будет достаточный уровень защищенности?
        • 0
          Вы на стороне сервера какой-нибудь обработкой строковых данных занимаетесь?

          \"Кавычки \". Cоставление запросов, слеши, SQL Injection
          • 0
            1.Нет, данные тупо инсертятся. На то они и данные) Вся обработка(парсинг) в js. Видимо из-за этого и нет проблем с кодировками.
            2. Спасибо за ссылку. Теперь более понятно с инъекциями. Честно говоря мне в горячем бреду бы не привиделось допустить ошибки, обработка которых описана в статье)
            В Двух словах - статья о том, как сделать всё через жопу(уж как есть говорю), а потом с этим бороться. Проще сразу нормально делать) + спасибо гугл за примеры хорошего кодинга. Тупо передирал у них всякие mysql_real_escape_string и как оказалось не зря)
            • 0
              Т.е. вы хотите сказать, что на habrahabr.ru, moikrug.ru, vkontakte.ru и market.yandex.ru всё сделано через жопу ;-) ?
              • 0
                К сожалению не знаю как сделано на перечисленных сайтах. Приведите пожалуйста пример кусочка исходников с одного из этих сайтов раз уж Вы знаете как они сделаны. Ну или какое то доказательство. Тогда и сможем оценить)
                Сильно сомневаюсь что они настолько пренебрегли архитектурой БД, что были вынуждены прибегнуть к динамически формируемым SQL запросам.
                • 0
                  Прошу прощения. Только теперь понял что вы о "Cоставление запросов, слеши, SQL Injection", а не о основной статье (http://habrahabr.ru/blog/webdev/32618.ht…).

                  Нет, по то как организована в перечисленных сайтах работа с БД не имею понятия. Я имел в виду JavaScript, xhtml, etc.
                  • 0
                    нема зашо)
            • 0
              А можно спросить, где там написано как все сделать через жопу?
    • НЛО прилетело и опубликовало эту надпись здесь
  • 0
    А заметьте, что 90% комментариев подразумевают использование PHP на стороне сервера. Это при том, что в соседних топиках идет флуд aka PHP suxx. Однако, парадокс..

    По теме: все в курсе про баг в IE на тему UTF-8 кодировки при AJAX-запросе? Или дополнить этот пробел в комменте?
    • 0
      Дополните пожалуйста: что вы имеете ввиду
      • 0
        В ситуации, когда страница отдана в браузер в UTF-8, и по действию пользователя с нее делается AJAX-запрос методом GET, в какой кодировке браузер должен отправлять данные?
        • 0
          Не совсем понял. Если запрос типа GET, то передаватся данные будут только через URL.
          Так в чём суть бага-то?
    • 0
      непременно дополнить.
  • 0
    еще бы оттипографить по человечески статью и будет отличное пособие
  • 0
    Спасибо за статью!

    Одно замечание - Ajax давно уже превратился из акронима (AJAX) просто в название, т.к. XMLHttpRequest используется не только в сочетании с XML.
  • 0
    если нужно юзать cp1251 использую такой вариант:

    JavaScript-аналог функций PHP urlencode и urldecode для cp1251

    var trans=[];
    var snart=[];
    for(var i=0x410;i<=0x44F;i++)
    {
    trans[i]=i-0x350;
    snart[i-0x350] = i;
    }
    trans[0x401]= 0xA8;
    trans[0x451]= 0xB8;
    snart[0xA8] = 0x401;
    snart[0xB8] = 0x451;
    window.urlencode = function(str)
    {
    var ret=[];
    for(var i=0;i<str.length;i++)
    {
    var n=str.charCodeAt(i);
    if(typeof trans[n]!='undefined')
    n = trans[n];
    if (n <= 0xFF)
    ret.push(n);
    }

    return window.escape(String.fromCharCode.apply(null,ret));
    }
    window.urldecode = function(str)
    {
    var ret=[];
    str = unescape(str);
    for(var i=0;i<str.length;i++)
    {
    var n=str.charCodeAt(i);
    if(typeof snart[n]!='undefined')
    n = snart[n];
    ret.push(n);
    }

    return String.fromCharCode.apply(null,ret);
    }
    </code>

    таким образом у клиента
    str = window.urlencode("строка в cp1251")
    а на сервере
    $str = urldecode($_REQUEST['str']);

    спасибо <a href='http://forum.vingrad.ru/act-ST/f-176/t-154562.html' >Aco</a>
  • 0
    фтопку олдскульные кодировки типа 1251, koi8 etc.
  • 0
    К чему статья, можно было написать 1 стрoкой iconv =\
  • 0
    большое спасибо!!!!!!!
  • 0
    Поиски привели меня на эту замечательную подборку:
    http://zhilinsky.ru/2007/08/10/php-unicode/
  • 0
    как раз то что нада!
    спасибо за статью,
    теперь уж точно навсегда решу проблему с русским аяксом,
    хотя в новых проектах юзаю конечно уже utf8
  • 0
    Ой спасибоо)))
    Вот напоролся очень жестко с тем, что на страничках windows-1251 аяксом передавался UTF-8
    И удивлялись: а что-й то у нас как-то криво работает… Эхх… век живи — век учись.
  • 0
    Для koi8-r создал раскладку:

    var trans_Koi8r = {«9472»:128,«9474»:129,«9484»:130,«9488»:131,«9492»:132,«9496»:133,«9500»:134,«9508»:135,«9516»:136,«9524»:137,«9532»:138,«9600»:139,«9604»:140,«9608»:141,«9612»:142,«9616»:143,«9617»:144,«9618»:145,«9619»:146,«8992»:147,«9632»:148,«8729»:149,«8730»:150,«8776»:151,«8804»:152,«8805»:153,«160»:154,«8993»:155,«176»:156,«178»:157,«183»:158,«247»:159,«9552»:160,«9553»:161,«9554»:162,«1105»:163,«9555»:164,«9556»:165,«9557»:166,«9558»:167,«9559»:168,«9560»:169,«9561»:170,«9562»:171,«9563»:172,«9564»:173,«9565»:174,«9566»:175,«9567»:176,«9568»:177,«9569»:178,«1025»:179,«9570»:180,«9571»:181,«9572»:182,«9573»:183,«9574»:184,«9575»:185,«9576»:186,«9577»:187,«9578»:188,«9579»:189,«9580»:190,«169»:191,«1102»:192,«1072»:193,«1073»:194,«1094»:195,«1076»:196,«1077»:197,«1092»:198,«1075»:199,«1093»:200,«1080»:201,«1081»:202,«1082»:203,«1083»:204,«1084»:205,«1085»:206,«1086»:207,«1087»:208,«1103»:209,«1088»:210,«1089»:211,«1090»:212,«1091»:213,«1078»:214,«1074»:215,«1100»:216,«1099»:217,«1079»:218,«1096»:219,«1101»:220,«1097»:221,«1095»:222,«1098»:223,«1070»:224,«1040»:225,«1041»:226,«1062»:227,«1044»:228,«1045»:229,«1060»:230,«1043»:231,«1061»:232,«1048»:233,«1049»:234,«1050»:235,«1051»:236,«1052»:237,«1053»:238,«1054»:239,«1055»:240,«1071»:241,«1056»:242,«1057»:243,«1058»:244,«1059»:245,«1046»:246,«1042»:247,«1068»:248,«1067»:249,«1047»:250,«1064»:251,«1069»:252,«1065»:253,«1063»:254,«1066»:255};

    window.urlencode_koi8r = function(str)
    {
    var ret=[];
    for(var i=0;i<str.length;i++)
    {
    var n=str.charCodeAt(i);
    if(typeof trans_Koi8r[n]!='undefined')
    n = trans_Koi8r[n];
    if (n <= 0xFF)
    ret.push(n);
    }

    return window.escape(String.fromCharCode.apply(null,ret));
    }
  • 0
    Кстати, если вы замучались и не понимаете почему UTF8 страница показывается каракулями, хотя meta прописана, то я просто добавлю, посмотрите в htaccess, скорее всего там одна строчка есть такая:
    AddDefaultCharset windows-1251

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.