jabber web-status

В процессе работы над Секретным Проектом™ образовался побочный продукт, который возможно покажется кому-то полезным. Суть «продукта» – показать статус вашего jabber-аккаунта в вебе, как это делается например для icq.

Для работы требуется добавить себе в ростер контакт webstatus@rpz.name, после этого ваш статус будет доступен по следующим ссылкам:

Сделано как обычно just for fun. Вы можете пользоваться этим сервисом как заблагорассудится, можете писать пожелания и комментарии, но не можете предъявлять претензии…

IE8 и currentStyle

Новость одной строкой… Когда-то я рассказал как добавить border-spacing для IE используя свойство currentStyle.

Вчера, как многие знают, вышел IE8.Собственно на этом можно было бы многозначительно пост закончить…

В общем в IE8 более этот трюк не работает. В currentStyle не попадают неизвестные браузеру свойства. Изящного решения пока не нашёл – если уж пользовались им, то просто замените непонятные буквы в css на cellSpacing = <число> вместо вычислений, которые были раньше…

Update а вот переводная статья о других особенностях IE8

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

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

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

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

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

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

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

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

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

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

28.11.08  |  ,  | 14 comments

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

ты не один

Приключилась сегодня очень познавательная история, мораль которой должен понимать любой разработчик, детище которого обслуживает более одного пользователя.

В рамках работ по выводу одного “неповоротливого асфальтоукладчика” на земную орбиту были проведены ряд его модернизаций. Испытания на тестовом полигоне показали что машина стала ездить на порядок быстрее и было решено доработки включить в работающий прототип(вроде и не первая космическая, но уже есть чем гордиться!). Но на первом же серьёзном показе зверь-машина с чудо{вищным} грохотом рассыпалась у всех на глазах и я сел в лужу…

А теперь тоже самое, но по-русски, с выражением.
Имеются ряд весьма тяжёлых для веба запросов к БД, результат которых условно не меняется в течении небольшого промежутка времени. Кеширование промежуточных результатов в самой БД нагрузку сняло на СУБД, но скрипты продолжали исправно тягать данные и это порой занимало внушительное время. Было решено результаты эти кешировать на стороне веб-сервера. Как хранилище был использован apc.

Первоначальный вариант выглядел примерно так:

if (!$data = cache_get($key)) {
   $data = data_from_db();
   cache_set($key,$data,$expire_time)
}

Без излишеств, просто и со вкусом. Но позже выснилось что “всё не так просто” и в зависимости от некоторых космических характеристик и результатов выборки из базы будет меняется ещё одна переменная (меняется переменная… ого!).

if (!$data = cache_get($key)) {
   $data = data_from_db();
   cache_set($key,$data,$expire_time);
   $other_data = some_function($data,$env);
   cache_set($other_key,$other_data,$expire_time);
} else {
   $other_data = cache_get($other_key);
}

Аляповато, но, чёрт возьми, работает…
Работало…
Должно было по идее работать…
Но, почему-то оказавшись на боевом, изрядно нагруженном, сервере это не сработало. Вернее это работало…, но не всё время… По истечении $expire_time периодически пропадали данные для $other_key. При отключении и/или очистке кеша работоспособность восстанавливалась… Кто виноват? Что делать? Кто за всё это ответит?!? Пришлось срочно пошевелить опилками.

Как мы все наверное догадываемся – реальный сервер обслуживает нереально много клиентов, причём не по очереди. И нет совершенно никаких гарантий на то, что между записью $key и $other_key не встрянет какой-либо маленький, но шустрый процесс (хотя нам это и не особо страшно), так же нет никаких оснований полагать что между выборкой $key и $other_key кто-то умный и большой не очистит кеш (целиком, или только $other_key – в данном эпизоде это не имеет значения).
Оснований не было, но я был почему-то твёрдо уверен, что “это если и происходит, то с кем-то другим”. С пониманием проблемы конечно же пришло и простое решение, но ошибка, согласитесь, совсем не тривиальная.

Так что мораль сей басни: помни – ты не один!

23.09.08  |   | стань первым

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