Как написать AJAX-приложение

18 Август, 2008 - 02:28 Корбмахер Артем info@webinfo.kz

Это 2 года обратно AJAX был в диковинку (конечно да а также самого слова AJAX в то время ещё никак не выдумали). Нынче веб-приложения, страницы которых обновляются "на лету", в порядке вещей. Пусть даже навыворот, кроме AJAX проблематично а также показать себе отдельные сервисы.

Как работали обыкновенные веб-приложения? Как положение, на событие (клик согласно ссылке или нажатие на кнопку) браузер реагировал отправкой запроса серверу. Когда вместе с сервера приходил ответ, всё содержимое страницы совсем обновлялось.

Одна из проблем состояла в том, что именно при обновлении содержимого страницы веб-приложение переходит в новое состояние. Из информации О предыдущем состоянии сохраняются лишь только данные, переданные в запросе. Чем сильнее точная информация О прежнем состоянии системы требуется, тем значительно больше данных должен быть пересылать в запросе.

Другим недостатком является необходимость пересылать повторяющиеся массивы данных клиенту затем каждого события. Например, в случае пользователь ошибся при заполнении формы, в таком случае взамен короткого сообщения об ошибке приходится опять загружать а также форму, а также всю введённую ранее информации.

Современные браузеры, поддерживающие стандарты W3C DOM, позволяют вывести веб-приложение на новый степень.

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

Веб-приложение получается распределенным, а также доля логики лежит на стороне клиента, но доля - на стороне сервера. Такие приложения а также называют термином "AJAX Applications" (аббревиатура расшифровывается как будто Asynchronous Javascript And Xml Applications).
Объект XMLHTTPRequest

Для асинхронных запросов от клиента к серверу на стороне браузера служит особый объект почти под названием XMLHTTPRequest.

Перечислим методы а также параметры объекта, какие будут использованы далее:
XMLHTTPRequest.open("method", "URL", async, "uname", "pswd") - образует запрос к серверу.
method - тип запроса, в частности, GET
URL - URL запроса, к примеру http://localhost/file.xml
async - в случае если True, так станет использоваться асинхронный запрос, в таком случае существует выполнение скрипта продолжится потом отправки запроса. В противном случае скрипт станет ожидать ответа от сервера, заморозив UI.
uname, pswd - логин а также пароль с целью простой веб-авторизации.
XMLHTTPRequest.send("content") - отправляет запрос на сервер. Значением content могут быть данные с целью POST-запроса или пустая строка.
XMLHTTPRequest.onreadystatechange - обработчик событий срабатывающий на всякое изменение состояния объекта. Состояния объекта могут быть следующими:
0 - вплоть до того как будто запрос отправлен (uninitialized)
1 - объект инициализирован (loading)
2 - получен ответ от сервера (loaded)
3 - объединение вместе с сервером активно (interactive)
4 - объект завершил работу (complete)
XMLHTTPRequest.responseText - возвращает полученные от сервера данные в виде строки.
XMLHTTPRequest.responseXML - при условии если ответ сервера пришел в виде правильного XML, возвращает XML DOM объект.
XMLHTTPRequest.status - возвращает статус HTTP-ответа в виде числа. Например, 404 при условии если запрашиваемая страница никак не была найдена на сервере.

Рассмотрим применение объекта на примере простого AJAX-приложения.
Поле SELECT вместе с поиском

Предположим около нас существует таблица, в которой порядка миллиона записей. Пользователю должен быть выбрать всего одну запись из таблицы (реализация отношения "один ко многим"). Выбор пользователя является всего только одним из этапов заполнения внушительный веб-формы.

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

В традиционном веб-приложении с целью этой цели пришлось бы приминять отдельную страницу а также сберегать остальные данные формы в сессии пользователя, или разбивать процесс заполнения формы на немножко этапов. В AJAX-приложении дополнительная страница далеко не нужна.

Выбор записи станет реализован вместе с помощью двух элементов веб-формы. Первый элемент - это текстовое поле, в каком месте пользователь вводит ключевое выражение. Оно отсылается на сервер, только тот возвращает всего лишь те строки из таблицы, какие удовлетворяют условию поиска. Ответ сервера (в виде списка) помещается в поле SELECT, в котором пользователь а также сделает окончательный выбор. Таким образом, при отправке всей формы на сервер попадет выбранное в поле SELECT значение в виде ID записи из внушительный таблицы.

В HTML выглядеть это вероятно таким образом:

На любое событие KeyUp (отжатие кнопки) в текстовом поле вызывается функция lookup ('текст', 'id-selecta', 'url')
function lookup(text, select_id, url)
// Получаем объект XMLHTTPRequest
if(!this.http){
this.http = get_http();
this.working = false;

this.http = get_http();
this.working = false;

// Запрос
if (!this.working && this.http) ЕжелиПри условии если в текстовом поле не более трёх
// символов - никак не делаем ничего
if (text.length <3 ) return;
//добавляем закодированный текст
//в URL запроса
url = url + "?text="+encodeURIComponent(text);
//создаём запрос
this.http.open("GET", url, true);
//прикрепляем к запросу функцию-обработчик
//событий
this.http.onreadystatechange = function()
// {44 - данные готовы с целью обработки
if (http.readyState == 4)
fill(select_id, http.responseText);
this.working = false;
else
// данные в процессе получения,
// {дозволенодозволено повеселить пользователя
//сообщениями
// ЖДИТЕ ОТВЕТА
}
}
this.working = true;
this.http.send(null);
}
if(!this.http)
alert('Ошибка при создании XMLHTTP объекта!')

}

Как заметно, в начале все мы получаем XMLHTTP-объект вместе с помощью функции get_http(). Затем поисковый текст кодируется в стиле URL а также формируется GET-запрос к серверу. URL запроса в данном случае станет выглядеть почти этак: http://localhost/cgi-bin/xmlhttp.cgi?text=...

Скрипт на сервере, получив значение text, мастерит розыск в таблице а также отсылает итог клиенту. В обработчике событий объекта XMLHTTP, в какое время данные от сервера получены а также готовы к использованию, вызывается функция fill('select_id', 'data'), которая заполнит перечень SELECT полученными данными.

Функция get_http() - это кросс-браузерная реализация получения объекта XMLHTTP (в каждом браузере он получается согласно-собственному). Её реализацию вместе с комментариями вы имеете возможность без затруднений разыскать в всемирной паутине, это, таким образом произнести, пример из учебника.
function get_http()
var xmlhttp;
/*@cc_on
@if (@_jscript_version >= {55)
try
xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
catch (e)
try {
xmlhttp = new
ActiveXObject("Microsoft.XMLHTTP");

xmlhttp = new
ActiveXObject("Microsoft.XMLHTTP");
catch (E)
xmlhttp = false;

}
@else
xmlhttp = false;
@end @*/
if (!xmlhttp && typeof XMLHttpRequest != 'undefined')
try {
xmlhttp = new XMLHttpRequest();

xmlhttp = new XMLHttpRequest();
catch (e)
xmlhttp = false;

}
return xmlhttp;
}

Функция fill() получает на вход значение параметра ID списка SELECT, кой должен быть заполнить, а также сами данные, полученные вместе с сервера.

Для простоты допустим, что именно данные вместе с сервера все мы получаем в виде таблицы, поля которой разделены символом табуляции 't', только строки - символом переноса строки 'n':
id1 t name1 n
id2 t name2 n
...

На основании содержимого этой таблицы все мы будем заполнять поле SELECT частями OPTION.
function fill (select_id, data)
// поле SELECT в переменную в виде объекта
var select = document.getElementById(select_id);
// очищаем SELECT
select.options.length = {00;
// в случае данных конечно нет - отнюдь не делаем незначительно больше ничего
if(data.length == 0) return;
// в массиве arr - строки полученной таблицы
var arr = data.split('n');
// ради каждой строки
for(var i in arr)
// в массиве val - поля полученной таблицы
val = arr[i].split('t');
// добавляем новый объект OPTION к нашему SELECT
select.options[select.options.length]=
new Option(val[1], val[0], false, false);

}

Готово. Нынче ради любой веб-формы приложения все мы можем реализовать сходный выбор значения из многомиллионного списка, кой с целью пользователя станет выглядеть как будто считанные нажатия клавиш. В локальной сети выбор происходит едва ли не мгновенно. В случае нестабильного или низкоскоростного соединения вместе с сервером, должен быть схоже оповещать пользователя О том, что сейчас загрузка данных вместе с сервера снова отнюдь не завершена. Полезно предусмотреть а также средства с целью реакции на обрыв соединения.