Технология AJAX

Кафедра: АСОИиУ
Лабораторная работа
На тему: AJAX
Душанбе, 2009
Введение
Ajax — технологияразработки Web-приложений, который использует код на машине клиента дляизменения данных на Web-сервере. В результате Web-страницы динамическиобновляются без перезагрузки полной страницы, прерывающей обмен данными. Спомощью Ajax вы можете создавать более богатые, более динамическиепользовательские интерфейсы для Web-приложений, которые приближаются поскорости и гибкости к приложениям, выполняющимся в клиентской части вашего кода.
Это два годаназад 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 запроса, например 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 выглядеть это может так:

onkeyup=«lookup(this. value, ‘id_select’,
‘http://localhost/cgi-bin/xmlhttp. cgi’)» />

На любоесобытие 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) {
var http = this. http;
// Если втекстовом поле менее трёх
// символов- не делаем ничего
if (text. length
// добавляемзакодированный текст
// в 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 запроса в данном случае будет выглядетьприблизительно так: 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;
}
}
return xmlhttp;
}
Функция 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] =
new Option(val [1], val [0], false,false);
}
}
Готово. Теперьдля любой веб-формы приложения мы можем реализовать подобный выбор значения измногомиллионного списка, который для пользователя будет выглядеть как считанныенажатия клавиш. В локальной сети выбор происходит практически мгновенно. Вслучае нестабильного или низкоскоростного соединения с сервером, необходимотакже оповещать пользователя о том, что загрузка данных с сервера еще незавершена. Полезно предусмотреть и средства для реакции на обрыв соединения.
Суть еесводится к следующему: осуществлять передачу данных (т.е. общение клиента ссервером) без фактической перезагрузки web-страницы. Естьнесколько реализаций этой идеи, данная статья раскажет о моей. При этом я неутверждаю, что ее не было до меня. Если была — я о ней не знал (на моментнаписания сего).
Для началапредлагаю определить, какие плюсы мы получаем, делая AJAX-скрипты.
1. Мыэкономим траффик как посетителя, так и свой собственный (у нас ведь платныйхостинг и за МБ мы платим:)).
2. Мыэкономим время посетителя.
3. Мыоблегчаем жизнь серверу — ему не приходится передавать каждый раз кучу «лишнего»HTML-кода.
4. В глазахпосетителя мы превращаем свой сайт в системную программу. Он жмет на кнопку ипрактически тут же видит результат.
Из личнойпрактики:
К примеру,раньше на WebFashion пользователь, чтобы выйти(очистить cookies), жал на «выход», ждалперезагрузки и, убедившись, что для системы он Гость, уходил с сайта. Теперь,он жмет «выход» и через мгновение видит изменение своего статуса(меняется верхнее навигационное меню).
Я думаю, ужене осталось сомнений, что AJAX имеет право насуществование на Вашем сайте. Остается только вопрос, как же реализовать идеюна практике. Сразу скажу, есть несколько больших и громоздких скриптов, мне онине понравились и я решил написать свой собственный скрипт.
Итак, как жединамически осуществить запрос к серверу и главное получить от неговразуметельный ответ? Я надеюсь, все знают о существовании тэга . Если не знаете, дальше можно не читать. Так вот,у него есть замечательный атрибут src. Значение этогоатрибута — адрес к JavaScript-файлу, спросите Вы? Несовсем. Это адрес к файлу, который содержит JavaScript-код.Чувствуете разницу? Т. е. этим файлом может быть php-файлс php-кодом, который после обработки сервером выведетнекий JavaScript, попутно сохраняя что-то в файлы,создавая cookies, изменяя БД и пр. Фактическипрограмма, создающая новую программу.
Передознакомлением со следующим абзацем еще раз прочитайте предыдущий, осознайте о чемидет речь, покурите и возвращайтесь.
Итак, Вывернулись, значит мы можем продолжить. На повестке дня еще несколько вопросов,но обо всем по порядку. Нам нужно динамически создавать в документе. Отведем для него специальный блок:

Стоитзаметить, что нам понадобится передавать параметры php-скрипту,а функции URL-кодирования в JavaScriptнет. Значит нужно создать нечто вроде таблицы кодирования (выводится элементарнымphp-скриптом и немного правится руками):
Дабы незабивать метр статьи, вкладываю файл.
Теперьнапишем функцию, которая будет динамически создавать .Функция принимает три параметра: адрес php-файла,массив имен передающихся переменных и массив значений этих переменных. Каждоезначение мы будем URL-кодировать.
function LoadScript(addr,query,str) {
// составлениестроки запроса
for(k = 0; k
{
str2 = “”;
// URL-кодируем (что такое chr смотримво вложенном файле)
for(j = 0; j
// добавляемк концу запроса «переменная=значение»
addr += query [k]+”=”+str2;
}
/*
* _ajax — идентификатор div-блока, ктозабыл.
* Немногопляшем с бубном:
* Писать в HTML только нельзя — IE ругается,
* поэтомудобавляем любую строчку, например «MSIE… ».
* Такженельзя одной строкой написать “”,
* разбиваемна две строки.
*/
_ajax. innerHTML = «MSIE… »;
/*
* даем JavaScript 10 мсек на осознание того, что _ajaxизменен
* иназначаем атрибут src.
*/
setTimeout(
function()
{
scr = _ajax. getElementsByTagName(«script») [0] ;
scr. language = «javascript»;
if (scr. setAttribute) scr. setAttribute(«src»,addr);
else scr. src=addr;
}
,
10);
}
Теперь,чтобы выполнить запрос index. php?action=view&id=49, нужно вызвать функцию LoadScript() следующимобразом:
LoadScript(«index. php»,Array(“? action”,”&id”),Array(«view»,«49»));
Длявыполнения скрипта без параметров следует передать функции LoadScript()его адрес и два пустых массива.
Вы спросите,как выдать некий результат из php-скрипта? В документе,из которого запускаем LoadScript(), создаем блок

А в php-скрипте пишем
echo
_hz. innerHTML=«работает!!!»;
a;
И теперьостается еще один маленький вопросик. Дело в том, что все скрипты, вызывающиесякак кэшируются браузером. Чтобы этого избежать, каждыйphp-скрипт начинаем с четырех строк:
Header(«Expires: Mon, 26 Jul 1997 05: 00: 00 GMT»);
Header(«Cache-Control: no-cache, must-revalidate»);
Header(«Pragma: no-cache»);
Header(«Last-Modified: ». gmdate(«D, d M Y H: i: s»).«GMT»);