Разберемся раз и навсегда: 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, любите людей, дарите подарки.
    Поделиться публикацией
    Реклама помогает поддерживать и развивать наши сервисы

    Подробнее
    Реклама
    Комментарии 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
                                      Мне, право, неловко, но всё же кириллические. ;-)
                                    • +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
                                                                            А заметьте, что 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

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