Cross Domain XMLHttpRequest

Задачи обмена информацией ставятся и успешно решаются каждый день. Но обмениваться можно по-разному. Кто-то дарит удобоваримый доступ к своей базе посредством распространённых обменных форматов (xml, csv, json, lisiy_chert), кто-то реализует собственные API, а кто-то идёт другими путями.

Моя задача состояла в следующем – на ресурсах-сателитах необходимо разместить сложную форму. “Сложность” формы заключается в том, что данные подгружаются с главного ресурса и не могут быть загружены единовременно(при загрузке ресурса) или доставлены на ресурс-сателит заранее (так-так данных очень много и они достаточно быстро устаревают). Всевозможные API для доступа к информации основного ресурса в настоящий момент разрабатывать нецелесообразно, поэтому было решено для сателитов предоставлять некий готовый комплекс (аля plug-n-play).

Ещё до начала разработки я тщательно изучил уже имеющиеся механизмы для межсайтового обмена данными. Первым и самым перспективным был вариант использования flash-плеера, но единственный вменяемый пример FlashXmlHttpRequest был только лишь примером, а не законченным куском кода, которым бы можно было воспользоваться. jQuery на тот момент даже не содержала функции $.getScript, JSHttpRequest с созданием тега script удачно справлялся, но POST по понятным причинам делать не мог.

Данные с главного ресурса могут подгружатся посредством динамического создания тега script jQuery.getScript, с этим казалось бы проблемы нет. Но! Но последним шагом в указанной форме нужно отправить на основной сервер внушительный объём данных, которые могут не влезть в GET (тоже кстати говоря весьма интересный вопрос – а каково ограничение на длину URL в разных браузерах? в различных веб-серверах,прокси и фильтрах? – в RFC2616 об этом не сказано). Можно конечно изобрести какие-либо механизмы, например отправлять данные небольшими порциями GET-ом, но скорости такая схема явно не прибавит, поэтому такие варианты оставлены другим изобретателям.
(more…)

03.10.08  |  ,  | 4 comments

firebug для отладки серверного кода


За последние пару лет firebug стал стандартным инструментом для отладки клиентской части веб-приложений у большинства разработчиков.
Тем, у кого это не так – от души сочувствую ;o)
Но многие не догадываются, что с помощью firebug можно отлаживать и серверный код. Не breakpoint-ами конечно. Но как замена унылым print-ам и var_dump-ам очень даже!

Собственно делается всё очень просто. Для того чтобы в консоли firebug-а появилось сообщение, необходимо написать js-код:

console.log('сообщение');
console.group('разные типы сообщений');
console.info('к вашему сведению, мы тут логи пишем...');
console.warn('предупреждаем о разном');
console.error('и информируем об ошибках!!!');
console.groupEnd();
console.dir({сложная: {структура: [1,2,3]}});

Подробнее о возможностях консоли firebug-а можно узнать в документации.

Дело за малым – сформировать эти строки на вашей серверной платформе.
Сложность представляет лишь последнее – json-упаковка сложных структур, но и она уже во многих платформах решена. Сам я пользуюсь функцией, описанной в коментариях к json_encode, т.к. родная слишком консервативна в вопросах кодировок(по стандарту в json можно упаковать только уникод, но браузеры более лояльны нежели писатели стандартов).

Собственно теперь чем это лучше всяких принтов и вар_дампов?
Тем, что не меняют визуально документ, что существенно в современных сложных веб-приложениях.
К тому же это в разы удобнее – все сообщения в одном месте, красиво представлены…

В заключение скажу о якобы готовых решениях для PHP:
Log::Firebug из PEAR – драйвер для довольно распространнённого pear::log
FirePHP – более комплексное решение, плагин к firebug-у и обёртка к серверному коду.

Я ни тем, ни другим не пользуюсь, т.к. первое сделано левой ногой, а второе заворачивает оригинальный документ в страшную multipart-кашу…

06.05.08  |  ,  | 2 comments

Всплытие покажет

Предположим у нас есть html-таблица 100×100 ячеек,в каждой ячейке – ссылка. При нажатии на каждую, должно происходить что-либо невероятное.
Мы можем сделать 10 тыс обработчиков onclick и медленно, но верно добиться своей цели.
А можем глупостей не делать. Ведь хватит только одного!


Дело в том, что события в DOM умею “всплывать” – т.е. если представить документ в виде слоёной структуры, где сам document находиться сверху, радуя глаз хрустящей корочкой, а все дочерние элементы под ним, то событие возбуждённое на нижних уровнях, не найдя свой законный обработчик у потревоженного объекта начинает потихоньку лезть наверх, шевеля всё на своём пути, и искать свой обработчик последовательно у всех предков.
Что это собственно даёт? Это может существенно сократить количество обработчиков событий на странице. На идеальной сферической странице вакуумного веб-приложения всего один обработчик!

Перейду к примерам: (more…)

05.05.08  |  ,  | 5 comments

jQuery 1.2.3

.4.5.6.7…

Тихо и незаметно зарелизился jQuery:

jquery-1.2.3.js, jquery-1.2.3.min.js, jquery-1.2.3.pack.js

Поскольку официального анонса пока нету, перечислю “вкусности” сам:
Вот официальный анонс, а ниже мой:
(more…)

07.02.08  |   | 3 comments

jQuery 1.2.2

К своему “второгодию” jQuery решил явиться миру обновлённым.

Много исправлений направленных на ускорение и “устабилизацию”.
Решена крайне досадная проблема с тем, что $(document).ready не срабатывал в IE если, документ находился в [и]фрейме.
Из новшеств – этот самый $(document).ready(func) теперь можно писать в более привычном виде через $.bind – $(document).bind(‘ready’,func);
Появились два новых event-а – mouseenter и mouseleave, которые вероятно скоро пойдут в массы в качестве основы для разнообразных dropdown-менюшек.
В “ajax”-части добавились “умолчальные” заголовки Accept, для разных типов dataType. (зачем это надо? и что из этого выйдет ?)

Перед тем как обновиться не забудьте – некоторые плагины могли “сломаться” – будьте готовы поработать напильником…

15.01.08  |   | 2 comments

Google using jQuery

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

Есть ещё сомневающиеся в правильности выбора jQuery? Или даже те, кто и вовсе ещё не выбрал? Задумайтесь! – даже гости из будущего почувствовали Великую Силу, которую даёт jQuery отбирая взамен лишь не многим больше 20кБ трафика.

Но овладеть магией не просто. А очень просто.

jQuery.facts II

Выдам ещё одну порцию фактов, связанных с jQuery.

  • jQuery.get() и jQuery.post() принимают последним четвёртым параметром dataType. Ну принимает и бог с ним, скажут некоторые. А другие смогут этот факт использовать во благо. Вот пример такого “блага”:
    $.post(backend_url,params,callback,’script’); // и вуаля – все вернувшееся с бэкэнда интерпретируется как javascript.Опять-таки внимательный (и просвещённый) читатель скажет “ну и нафига? есть же jQuery.getScript ?”. Тут мне ответить уже нечего. Разве что напомнить о том факте, что getScript передаёт параметры GET-ом, длина которого как мы знаем весьма ограничена.
  • Кстати о jQuery.getScript() – начиная с версии 1.2.1 getScript умеет кросс-доменные запросы (все урлы начинающиеся с http автоматом будут тянуться не через XmlHttpRequest, а посредством добавления тега script). Это открыло нам такие просторы, что ни в сказке сказать, ни трактором убрать… (правда имеется одно досадное недоразумение, но видимо оно беспокоит только меня UPDATE: пофиксили).
  • Не совсем jQuery, но тоже важный факт – расчудесный плагин jQuery.livequery аналог Behaviour – помогающий создавать скрипты работающие “на манер css”.
    $('span.bugaga').livequery('click',function(){
       alert('Бугага');
    });
    $('span.gygygy').livequery(function(){
       $(this).bind('click',function(){
          alert('Надо же - кликнули. Гыгыгы');
       });
       alert('В документе появились span-ы c классом gygygy');
    });
    

    Поясняю – работает это так же как и jQuery.bind, за одним лишь исключением – элементов на странице к моменту вызова функции может и не быть. Когда они появяться – livequery “навесит” на них нужные обработчики. Очень удобно. Но будьте внимательны и осторожны – не стоит увлекаться – чем больше элементов будут переданы в livequery, тем “тормознее” будет система – каждые 20мс проводиться поиск элементов в целью найти и обезвредить навесить нужные эвенты (а также после разнообразных манипуляций с dom).

  • И последний на этот раз факт – как известно jQuery “оборачивается” в функцию $() – уж больно кратко,красиво и удобно в использовании. Но в эту же функцию любят “оборачиваться” многие известные js-фреймворки. И это казалось бы ставит крест на совместном их использовании… Но не в случае с jQuery – его авторы понимают что они не одни на белом свете. jQuery.noConflict(); “отпустит” функцию $(), правда сам код использующий jQuery в этом случае должен содержать либо полное название функции [ jQuery("selector").action(); ] или же должен быть “завёрнут” в анонимную функцию [ (function($) { original_code})(jQuery); ]