Аякс за 30 секунд

28 Nov, 2005

Перевожу заметку с которой я начал свое знакомство с аяксом.
Находится на сайте Rasmus'a - Rasmus' 30 second AJAX Tutorial.
Мой вольный перевод.
Вообще сам Аякс я считаю немного обманом. Многие использовали те же самые приемы задолго до того как они вдруг стали "Аяксом". И эти вещи совсем не такие сложные как многие считают. Вот простой пример из одного из моих приложений.
Сначала Javascript:

function createRequestObject() {
    var ro;
    var browser = navigator.appName;
    if(browser == 'Microsoft Internet Explorer'){
        ro = new ActiveXObject('Microsoft.XMLHTTP');
    }else{
        ro = new XMLHttpRequest();
    }
    return ro;
}

var http = createRequestObject();

function sndReq(action) {
    http.open('get', 'rpc.php?action='+action);
    http.onreadystatechange = handleResponse;
    http.send(null);
}

function handleResponse() {
    if(http.readyState == 4){
        var response = http.responseText;
        var update = new Array();

        if(response.indexOf('|' != -1)) {
            update = response.split('|');
            document.getElementById(update[0]).innerHTML = update[1];
        }
    }
}

Этот код создает обьект запроса, сам запрос и функцию для его принятия и распарсивания(по названиям, собственно, нетрудно догадаться). Для использования вам нужно включить этот скрипт в вашу страницу. (<script type="text/javascript" src="js.js"></script>)
Теперь для того чтобы послать запрос нужно его прицепить к какому-нибудь событию. Например onclick или поместив прямо в href вот так:

  1. <a href="javascript:sndReq('foo')">[foo]</a>
Это означает что при клике на эту ссылку будет отослан вот такой запрос rpc.php?action=foo.

В rpc.php у вас может быть примерно такой код:

  1. switch($_REQUEST['action']) {
  2. case 'foo': /*...action=foo...*/
  3. /* тут например запрос к базе*/
  4. echo "foo|foo done";
  5. break;
  6. ...
  7. }
Теперь обратим внимание на handleResponse. Оно распарсивает строку "foo|foo done" и разделяет ее по символу '|'. Причем использует то что было до '|' - как id блока в HTML, а то что после - как новый innerHTML для этого блока. В данном случае, если у вас на странице есть вот такой HTML:
  1. <div id="foo">
  2. </div>
То как только вы кликните на ссылку, он динамически изменится на:
  1. <div id="foo">
  2. foo done
  3. </div>
Вот собственно и все. Остальное лишь надстройка над этим простым скриптом. Заменяйте мой простой ответ от сервера "id|text" на более богатый формат XML, и делайте запрос сложнее чем просто с одной переменной. Перед тем как вы слепо установите одну из тысяч "AJAX" библиотек попробуйте сами добавить в этот скрипт нужный вам функционал, чтобы понять как именно оно работает и усложнить его ровно настолько насколько это вам нужно. Очень часто нужно не намного больше этого моего примера.

Обобщить этот подход, например для отсылки нескольких переменных, было бы очень просто, примерно так:

  1. function sndReqArg(action,arg) {
  2. http.open('get', 'rpc.php?action='+action+'&arg='+arg);
  3. http.onreadystatechange = handleResponse;
  4. http.send(null);
  5. }

А функцию handleResponse можно легко расширить для более интересных целей, чем просто замещение содержимого ДИВа.

Автор - Rasmus

В конце

Вот такая вот статейка. На ее базе мне например хватило 2Кб скрипта для создания вот такой вот фичи для укр.нета (исходники). Не без помощи CB правда. :) Джаваскриптер из меня все же слабенький. Прошу прощения за местами косноязычный перевод - я старался :). Считаю это одним из лучших тюториалов для начала работы с аяксом.

Хотя бы потому, что лично мне претит использовать все эти навороченные библиотеки. Это как использовать сложную ЦМС для сайта с 3 статическими страницами. Такие вот ассоциации. И это не говоря о пушках и воробьях.

Ваше мнение по поводу тюториала приветствуется!

45 комментариев к “Аякс за 30 секунд”

1.ganges | 28 Nov, 2005
"Тьюториал" - класс, АктивХ -ффу Сорри за ОТ
2.A.I. | 29 Nov, 2005
Кстати, есть и более простой способ AJAX'а: function sndReq(page) { document.write(''); } Правда я не очень уверен, что он везде работает (в Mozilla и Opera 8 точно работает).
3.Rico+script.aculo.us at Staranger than Fiction | 29 Nov, 2005
[...] Решил и я наконец познакомиться с Ajax’ом поближе… [...]
4.Attlant | 29 Nov, 2005
Можно исходнки в архиве?
5.akella | 29 Nov, 2005
2AI: Ты наверно имел ввиду - эту статью? Мне, честно говоря, это не видится более простым способом. Кроме того в принципе корявоватым, хотя и более кроссбраузерным. Но это лишь ИМХО. 2Attlant: я добавил линк
6.tobto_ | 29 Nov, 2005
>> Это как использовать сложную ЦМС для сайта с 3 статическими страницами Это точно, относительно моего опыта с друпалом. Вещь титаническая, но на локале 1.5 s перезагрузки на одну страницу. Странная вещь - я видел сайты серъезных людей, там где действительно было сделано 3 стр. на друпале. Вот это круто. Главное, - монументально. Относительно ajax: я пользуюсь постоянно IE5.5, Op9, FF0.9.3 и сравниваю результаты. Заметил, что ресурсы сделанные на AJAX обламываются скорее, чем обычные. Типично, выскакивает алерт: "Не могу послать HttpRequest". Возникает впечатление, что ajax хочет стабильной связи - иначе посыл броузера зависает. И это при выделенке.
7.mcbn | 30 Nov, 2005
occide se de parietam.. XML sockets выброси на помойку. А вот куда идти читать: http://dklab.ru/lib/Subsys_JsHttpRequest
8.Антон Бо | 30 Nov, 2005
Шустренький, маленький (JS меньше килобайта), до тупого простой, сменщик innerHTML — AHAH: http://microformats.org/wiki/rest/ahah :) Хоть я и далёк от JS, но не вижу причин не пихать в запрос параметры, а с той стороны иметь, например, php. Поправьте, если чего.
9.mcbn | 30 Nov, 2005
Антон - в дестку(е) !
10.mcbn | 30 Nov, 2005
сказано же, что XMLHttpRequest менее практичен. ActiveX как никак. А на dklab.ru сделано 2 варианта в одном флаконе.
11.akella | 30 Nov, 2005
сказано же, что XMLHttpRequest менее практичен
Мне это видится воркараундом - а не бест практис.. Что значит менее практичен? Видимо этот вопрос исчерпывается Оперой и отключенным ActiveX. К тому же та библиотека использует XMLHttpRequest если он доступен. А поддерживать совсем старые броузеры невыгодно из-за других расхождений в понимании ДЖС. Это все равно что юзать всякие HTML атрибуты вместо CSS. XMLHttpRequest для того только и был придуман. А писать <script> временное решение для некоторых броузеров. К тому же мне совершенно неинтересно было предлагать какую то супер библиотеку-скрипт которая решит все ваши проблемы. Такие решения по умолчанию неоптимальны. К чему вам библиотека если можно обойтись половиной ее функций? Зачем вам ЦМС если можно создать три статических страницы? Как раз наоборот, я хотел показать то, с чего можно начать знакомиться с аяксом - я больше чем уверен что любое приложение на базе библиотеки займет куда больше байт чем мое заточеное под задачу - без ничего лишнего. К тому же будет труднее для понимания. 2 Антон Бо: спасибо за линк - в принцпе это одно и тоже с тем что описано в статье - просто развитая мысль - и по другому скомпонованы функции. Кому как удобнее..
Хоть я и далёк от JS, но не вижу причин не пихать в запрос параметры, а с той стороны иметь, например, php. Поправьте, если чего.
Видимо ты не до конца понял что и там и у меня они пихаются абсолютно одинаково... Еще раз скажу: Это не очередная библиотека - это тьюториал для начинающих. Если вам легче брать библиотеку(UltraUniversalAJAX) и разбираться в ней - пожалуйста - некоторым(мне :)) проще разобраться от самого начала и писать свои решения и не использовать библиотеки...
12.mcbn | 01 Dec, 2005
Дело в том, что ActiveX блокируют много пользователей собственноручно. Разговор уже не о том, что Опера такая-секая. Во-вторых, ActiveX блокируется по умолчанию множеством МСЭ ( персональных, конечно ). Да и IE последних версий ругается. Нет, на самом деле, детский сад обсуждать ActiveX компноненты. Всё уже пережёвано до неузнаваемости. Тот вариант, который я предложил, хорош тем, что в обсуждаемом классе реализуется, и ActiveX-управление, и, пардон, не-ActiveX. Да и "разбираться" в них никто не заставляет. Не хотите - сами напишите.
13.akella | 01 Dec, 2005
Понятно что тот универсальнее - но далеко не такой легкий для понимания сразу. И все же - ну некрасивый он. А это собссно перевод очень хорошего как по мне тьюториала для начала работы. Когда уж заморочимся на поддерживаемости - можно и тот использовать. Кстати
Дело в том, что ActiveX блокируют много пользователей собственноручно.
Есть ли статистика? Мне почему-то кажется что проблема отключенного джаваскрипта родственна в статистическом смысле этой. То есть очень сильно меньше 1%. Лишь кажется - если бы статистику...
14.mcbn | 01 Dec, 2005
1. Ну, уж если сложно... 2. Конечно, статистика! Не от былды же говорю.
15.akella | 01 Dec, 2005
ну... ссылка на статистику? Я и так понял что ты убежден что их много с отключенным ActiveX. Мне интересна статистика откуда ты почерпнул такую информацию. Я к сожалению не смог найти... Я не отрицаю - но мне интересно сколько и по чьим данным?
16.mcbn | 01 Dec, 2005
Вот ещё.. ссылки искать буду. Прийду домой, гляну в хистори, если успею %)
17.akella | 05 Dec, 2005
Без статистики - все пустые слова...
18.mcmx | 11 Dec, 2005
Поправте мня, если я не прав: В статье показан скорее _ПОДХОД_ чем _КОНКРЕТНАЯ РЕАЛИЗАЦИЯ_ , а DK либа - это уже некое решение, предусматривающее реальную ситуацию. 2akella - Статья понравилась, и оч много идей подкинула по моему сайту. однако в опере на ukrnet не работает однако совершенно.... :)
19.akella | 12 Dec, 2005
Конечно подход. Или скорее путь по построению библиотеки под конкретные нужды. или даже просто начало знакомства с технологией с самого начала а не с библиотек. А для оперы надо добавить создание еще одного обьекта в функцию createRequestObject - msxml2 или типа того. Потому и не работает - старался сделать максимально приближенным к статье...
20.mcmx | 12 Dec, 2005
У меня опера 8.5 стоит, в ней XMLHttpRequest работает. Но одна деталь, которая меня бесит... В ответ на navigator.appName она нагло заявляет, что она 'Microsoft Internet Explorer'(!!!) поэтому немного поправленый кусок кода вполне работает (по крайней мере в 8.5) function createRequestObject() { var ro; var userAgent=navigator.userAgent; if (userAgent.indexOf('MSIE') != -1) { if (userAgent.indexOf('Opera') != -1) // Собственно интересуемся "А не опера ли ты часом?" { ro = new XMLHttpRequest(); } else { ro = new ActiveXObject('Microsoft.XMLHTTP'); } } else { ro = new XMLHttpRequest(); } return ro; } Все остальное - как у тебя.
21.akella | 13 Dec, 2005
Если уж говорить о кроссбразуерных- то вот такой код "общепринят":
var xmlHttp = false;
/*@cc_on @*/
/*@if (@_jscript_version >= 5)
try {
 xmlHttp = new ActiveXObject('Msxml2.XMLHTTP');
} catch (e) {
 try {
 xmlHttp = new ActiveXObject('Microsoft.XMLHTTP');
 } catch (e2) {
 xmlHttp = false;
 }
}
@end @*/

if (!xmlHttp && typeof XMLHttpRequest != 'undefined') {
 xmlHttp = new XMLHttpRequest();
}
взято с отсюда
22.mcmx | 13 Dec, 2005
Небуду стучать пальцами об двери, я не слишком силен в JS :) Я вообще дизайнер и старый сионист, PHP-шник по надобности. :) А за инфу спаибо, буду пробовать.
23.CB | 13 Dec, 2005
Мой последний вариант
function createRequestObject()
{
 var ro;

 if (window.XMLHttpRequest) { ro = new XMLHttpRequest(); }
 else {
 ro = new ActiveXObject('Msxml2.XMLHTTP');
 if(!ro) { ro = new ActiveXObject('Microsoft.XMLHTTP'); }
 }

 return ro;
}
24.mcmx | 13 Dec, 2005
И всетаки интересно, какой модели придерживается опера.
25.CB | 13 Dec, 2005
ro = new ActiveXObject('Msxml2.XMLHTTP'); Эта строка для Опер (в моем варианте) Имхо по имени браузер определят не очень надежно
26.mcmx | 14 Dec, 2005
по appName - ненадежно. по userAgent - вполне :) В моем примере какраз по имени отсекает достаточно точно. просто в последних операх какого то ляда они стали притворятся IE . Твой вариант компактнее - спору нет :) но он плодит сообщения об ошибках у фокса :(
27.CB | 14 Dec, 2005
2 mcmx: А можно поподробнее об ошибках у фокса. У меня все вроде гладко работает (код выдран с рабочего скрипта на судоку.орг.уа), ЖС-консоль девственно чиста :)
28.mcmx | 14 Dec, 2005
Ой... сори, я бок запорол... поправил - все ок...
29.CB | 23 Dec, 2005
http.readyState: 0 = uninitialized 1 = loading 2 = loaded 3 = interactive 4 = complete tnx to DiGiTAL
30.Илья Барков | 09 Jan, 2006
Спасибо за перевод! То, что я искал!
31.Jeje | 22 Jan, 2006
Опера предваряется IE скорее всего из-за настроек в ней Зайдите в Tools->Preferences->Advanced->Network->Browser Identification
32.intenter | 23 Mar, 2006
Если тема интересна, то вот еще пара очень простых примеров с описанием: AJA - AJAX без XML Опрос с помощью AJAX
33.CB's blog | 30 Mar, 2006
[...]перевод можно найти тут. Уверен, что уже после того как вы их прочитаете, сразу возникнет желание чтото реализовать и самому [...]
34.SOb | 20 May, 2006
Замечу, что на сайте http://cssing.org.ua/ajax/ блок с содержимым новости было бы здорово позиционировать относительно координат мыши (clientX, clientY). Ниже на 10px, например.
35.Gart | 02 Aug, 2006
А кто подскажет: при возврате ответа с сервера кирилица выводится кракозабрами? как это подлечить?
36.akella | 01 Oct, 2006
Проставь в php скрипте который отправляет ответ - кодировку. функцией header, например: header("Content-type: text/html; charset=UTF-8");
37.Vladson | 02 Oct, 2006
akella почини RSS у каментов, у тебя там ампрессанды не фильтруются... (в "title")
38.KeTal | 24 Dec, 2006
Респект! То что надо!
39.Костя | 10 Feb, 2007
mcbn сказал(а) "XMLHttpRequest менее практичен. ActiveX как никак" А вот Аякс без ActiveX и XMLHttpRequest. (http://webdesign.site3k.net/consulting/ajax.html) mcmx сказал(а) "опера... она нагло заявляет, что она ‘Microsoft Internet Explorer’" Это зависит от того, как ты ее настроиш. Но вот точное определение браузера. Однако в случае Аякса, лучше ориентироваться не на имя браузера, а на то, работает модуль, или нет. То есть: if(window.XMLHttpRequest){тут код}
40.Powermic | 26 Feb, 2007
Очень полезная статья, автору, переводчику и постерам мега респект.
41.Vladson | 27 Feb, 2007
Мне на эту тему больше нравится http://developer.mozilla.org/en/docs/AJAX:Getting_Started и просто и информативно...
42.Sliper | 05 Feb, 2010
Мне помогло следующее (кодировка всего сайта windows-1251): в корневом .htaccess нужно добавить следующую стоку AddDefaultCharset windows-1251 После этого вопросительные знаки пропали...
43.dark-demon | 24 May, 2007
ещё один ультракомпактнокроссбраузерный аякс ^_^ http://darkodemon.blogspot.com/2007/05/blog-post_5931.html
44.Max | 20 Jun, 2007
Здравствуйте. Проблема ... function handleResponse() { if(http.readyState == 4){ var response = http.responseText; document.getElementById('foo').innerHTML = response; } } ... после выполнения замес-то слов вопросительные знаки присылает, почему?
45.akella | 20 Jun, 2007
почитайте комментарий #36