Кафедра: АСОИиУ
Лабораторная работа
На тему: AJAX
Душанбе, 2009
Ajax - технология разработки Web-приложений, который использует код на машине клиента для изменения данных на Web-сервере. В результате Web-страницы динамически обновляются без перезагрузки полной страницы, прерывающей обмен данными. С помощью Ajax вы можете создавать более богатые, более динамические пользовательские интерфейсы для Web-приложений, которые приближаются по скорости и гибкости к приложениям, выполняющимся в клиентской части вашего кода.
Это два года назад AJAX был в диковинку (да и самого слова AJAX тогда ещё не выдумали). Теперь веб-приложения, страницы которых обновляются "на лету", в порядке вещей. Даже наоборот, без AJAX трудно и представить себе некоторые сервисы.
Как работали обычные веб-приложения? Как правило, на событие (клик по ссылке или нажатие на кнопку) браузер реагировал отправкой запроса серверу. Когда с сервера приходил ответ, всё содержимое страницы полностью обновлялось.
Одна из проблем состояла в том, что при обновлении содержимого страницы веб-приложение переходит в новое состояние. Из информации о предыдущем состоянии сохраняются только данные, переданные в запросе. Чем более точная информация о прежнем состоянии системы требуется, тем больше данных необходимо пересылать в запросе.
Другим недостатком является необходимость пересылать повторяющиеся массивы данных клиенту после каждого события. Например, если пользователь ошибся при заполнении формы, то вместо короткого сообщения об ошибке приходится снова загружать и форму, и всю введённую ранее информации.
Современные браузеры, поддерживающие стандарты W3CDOM, позволяют вывести веб-приложение на новый уровень.
Схема взаимодействия остается почти такой же. Вот только отправляет запрос и получает ответ с сервера теперь скрипт на стороне клиента, а вместо обновления всей страницы - обновляется только ее часть (вместо обновления могут предприниматься иные действия, например, отправляться следующий запрос).
Веб-приложение получается распределенным, и часть логики находится на стороне клиента, а часть - на стороне сервера. Такие приложения и называют термином "AJAXApplications" (аббревиатура расшифровывается как AsynchronousJavascriptAndXmlApplications).
Для асинхронных запросов от клиента к серверу на стороне браузера служит специальный объект под названием 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, возвращает XMLDOM объект.
XMLHTTPRequest. status - возвращает статус HTTP-ответа в виде числа. Например, 404 если запрашиваемая страница не была найдена на сервере.
Рассмотрим применение объекта на примере простого AJAX-приложения.
Предположим у нас есть таблица, в которой порядка миллиона записей. Пользователю необходимо выбрать всего одну запись из таблицы (реализация отношения "один ко многим"). Выбор пользователя является всего лишь одним из этапов заполнения большой веб-формы.
Естественно, для того, чтобы пользователь мог выбрать нужную запись из миллиона, нужны какие-то средства поиска этой самой записи. Например, простой текстовый поиск по наименованию.
В традиционном веб-приложении для этой цели пришлось бы использовать отдельную страницу и сохранять остальные данные формы в сессии пользователя, либо разбивать процесс заполнения формы на несколько этапов. В AJAX-приложении дополнительная страница не нужна.
Выбор записи будет реализован с помощью двух элементов веб-формы. Первый элемент - это текстовое поле, где пользователь вводит ключевое слово. Оно отсылается на сервер, а тот возвращает только те строки из таблицы, которые удовлетворяют условию поиска. Ответ сервера (в виде списка) помещается в поле SELECT, в котором пользователь и сделает окончательный выбор. Таким образом, при отправке всей формы на сервер попадет выбранное в поле SELECT значение в виде ID записи из большой таблицы.
В HTML выглядеть это может так:
<input type="text"
onkeyup="lookup(this. value, 'id_select',
'http://localhost/cgi-bin/xmlhttp. cgi')" />
<select id="id_select" name="id_select">
<option selected="selected" value=""></option>
</select>
На любое событие KeyUp (отжатие кнопки) в текстовом поле вызывается функция lookup ('текст', 'id-selecta', 'url')
function lookup(text, select_id, url) {
// Получаем объект XMLHTTPRequest
if(! this. http) {
this. http = get_http();
this. working = false;
}
// Запрос
if (! this. working && this. http) {
varhttp = this. http;
// Если в текстовом поле менее трёх
// символов - не делаем ничего
if (text. length <3) return;
// добавляем закодированный текст
// в URL запроса
url = url + "? text="+encodeURIComponent(text);
// создаём запрос
this. http. open("GET", url, true);
// прикрепляем к запросу функцию-обработчик
// событий
this. http. onreadystatechange = function() {
// 4 - данные готовы для обработки
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 >= 5)
try {
xmlhttp = new ActiveXObject("Msxml2. XMLHTTP");
} catch (e) {
try {
xmlhttp = new
ActiveXObject("Microsoft. XMLHTTP");
} catch (E) {
xmlhttp = false;
}
}
@else
xmlhttp = false;
@end @*/
if (! xmlhttp && typeof XMLHttpRequest! = 'undefined') {
try {
xmlhttp = new XMLHttpRequest();
} catch (e) {
xmlhttp = false;
}
}
returnxmlhttp;
}
Функция fill() получает на вход значение параметра ID списка SELECT, который необходимо заполнить, и сами данные, полученные с сервера.
Для простоты предположим, что данные с сервера мы получаем в виде таблицы, поля которой Разделены символом табуляции 't', а строки - символом переноса строки 'n':
id1tname1n
id2tname2n
На основании содержимого этой таблицы мы будем заполнять поле SELECT элементами OPTION.
function fill (select_id, data) {
// поле SELECT в переменную в виде объекта
var select = document. getElementById(select_id);
// очищаем SELECT
select. options. length = 0;
// если данных нет - не делаем больше ничего
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] =
newOption(val [1], val [0], false, false);
}
}
Готово. Теперь для любой веб-формы приложения мы можем реализовать подобный выбор значения из многомиллионного списка, который для пользователя будет выглядеть как считанные нажатия клавиш. В локальной сети выбор происходит практически мгновенно. В случае нестабильного или низкоскоростного соединения с сервером, необходимо также оповещать пользователя о том, что загрузка данных с сервера еще не завершена. Полезно предусмотреть и средства для реакции на обрыв соединения.
Суть ее сводится к следующему: осуществлять передачу данных (т.е. общение клиента с сервером) без фактической перезагрузки web-страницы. Есть несколько реализаций этой идеи, данная статья раскажет о моей. При этом я не утверждаю, что ее не было до меня. Если была - я о ней не знал (на момент написания сего).
Для начала предлагаю определить, какие плюсы мы получаем, делая AJAX-скрипты.
1. Мы экономим траффик как посетителя, так и свой собственный (у нас ведь платный хостинг и за МБ мы платим:)).
2. Мы экономим время посетителя.
3. Мы облегчаем жизнь серверу - ему не приходится передавать каждый раз кучу "лишнего" HTML-кода.
4. В глазах посетителя мы превращаем свой сайт в системную программу. Он жмет на кнопку и практически тут же видит результат.
Из личной практики:
К примеру, раньше на WebFashion пользователь, чтобы выйти (очистить cookies), жал на "выход", ждал перезагрузки и, убедившись, что для системы он Гость, уходил с сайта. Теперь, он жмет "выход" и через мгновение видит изменение своего статуса (меняется верхнее навигационное меню).
Я думаю, уже не осталось сомнений, что AJAX имеет право на существование на Вашем сайте. Остается только вопрос, как же реализовать идею на практике. Сразу скажу, есть несколько больших и громоздких скриптов, мне они не понравились и я решил написать свой собственный скрипт.