ЛАБОРАТОРНАЯ РАБОТА № 18 (9 JavaScript)

Тема: Технология AJAX

Цель: Изучение особенностей технологии AJAX для получения данных с сервера

ОГЛАВЛЕНИЕ

1 Технология AJAX
1.1 Особенности технологии AJAX
1.2 Использование объекта XMLHttpRequest
1.2.1 Создание объекта xmlHttp
1.2.2 Формирование запроса к серверу
1.2.3 Получение данных из сервера
Пример 1
Пример 2
Индивидуальные задания

1 Технология AJAX

1.1 Особенности технологии AJAX

AJAX (Asynchronous JavaScript And XML - асинхронный JavaScript и XML) представляет собой технологию, позволяющую при необходимости в фоновом режиме (не прерывая работы пользователя и незаметно для него) выполнять запросы к серверу и получать дополнительные данные для обновления отдельных частей Web-страницы, тем самым исключая необходимость повторной загрузки страницы. Например, выполнять на стороне сервера проверку правильности заполнения данных пользоваетелем по мере их ввода.
Без использования технологии AJAX для решения этой задачи имеются такие возможности:

Для применения AJAX необходимы следующие компоненты:

Первоначально технологию AJAX разработала фирма Microsoft как объект ActiveX для браузера Internet Explorer. Затем фирма Mozilla создала объект XMLHttpRequest с (почти) идентичными API, который в настоящее время поддерживается всеми современными браузерами.
Рекомендации организации W3C аналогичной функциональности пока не применены ни в одном браузере.
Оглавление

1.2 Использование объекта XMLHttpRequest

Объект XMLHttpRequest дает возможность отправлять асинхронные HTTP-запросы из кода JavaScript серверу, принимать от него ответы и обновлять отдельные части Web-страницы, не прерывая работу пользователя. Имеет следующие методы и свойства:

Использование методов и свойств объекта XMLHttpRequest приведено в примере № 1, в котором выполняется получение текстовых данных из локального сервера, и в примере № 2, в котором выполняется получение случайных чисел из удаленного сервера. В этих примерах осуществляется:

Оглавление

1.2.1 Создание объекта xmlHttp

Создание объекта xmlHttp осуществляется с помощью функции createxmlHttp(). Поскольку объект xmlHttp создается в обоих примерах (№ 1 и № 2), оператор присвоения, вызывающий функцию createxmlHttp() и сама функция описаны во внешнем файле ajax.js:

xmlHttp=createxmlHttp();
function createxmlHttp()
{
try
{
var xmlHttp=new XMLHttpRequest(); //var делает переменную локальльной
}
catch(e)
{
xmlHttp=new ActiveXObject("Microsoft.XMLHttp");
}
if(!xmlHttp) alert("Объект xmlHttp не создан");
else return xmlHttp;
}

Функция createxmlHttp() содержит конструкцию try/catch, которая используется для проверки того, выполняется ли некоторый код JavaScpipt без ошибок:
try
{
// Проверяемый код
}
catch(e)
{
// Обработка ошибки
}

Проверяемый код помещается в блок try{}. Если при выполнении кода произошла ошибка (возникла исключительная ситуация), то управление передается блоку catch(e){}, который перехватывает возникшее исключение и обрабатывает ошибку. При этом исключение не доходит до интерпретатора JavaScpipt и поэтому не сообщается пользователю. Если в блоке try{} код выполняется без ошибок, то блок catch(e){} управление не получает вовсе.
Как отмечалось выше, современные браузеры поддерживают работу с XMLHttpRequest. Однако это не относится к браузерам IE версии 6 и ниже. Поэтому функция createxnlHttp() сначала пытается создать объект xmlHttp с помощью класса XMLHttpRequest (блок try{}). Если при этом возникает исключительлная ситуация, управление передается в блок catch(e){}, где делается попытка создать объект xmlHttp уже с помощью объекта ActiveXObject.
Если объект и при этом создать не удается, то выводится сообщение о том, что объект xmlHttp не создан.
Оглавление

1.2.2 Формирование запроса к серверу

После создания объекта xmlHttp можно использовать его методы и свойства для организации запроса к серверу. Это делается с помощью функции process(), которая как и функция createxnlHttp() используется в примерах № 1 и № 2 и хранится в файле ajax.js:

function process()
{
if(xmlHttp)
{
try
{
xmlHttp.open("GET",serverAddr+serverPar,true);
xmlHttp.onreadystatechange=handleStateChange;
xmlHttp.send(null);
}
catch(e)
{
alert("Невозможно соединится с сервером:\n"+e.toString()+ "\n"+e.description);
}
}
}

Функция process() сначала проверяет, создан ли объект xmlHttp. Если создан, то выполняются следующие действия:

При возникновении исключительной ситуации на экран выводится сообщение о невозможности соединения с сервером, к которому добавляется перехваченное сообщение e, преобразованное в строку.
Имеется две возможности преобразования e:

Функция process() использует обе эти возможности. При этом в случае, например, неправильного задания URL-адреса сервера на экране появляются следующие сообщения:

Невозможно соединится с сервером
[object Error]
Отказано в доступе
Оглавление

1.2.3 Получение данных из сервера

Получение данных из сервера выполняется по разному в примере № 1 и в примере № 2, поэтому будет рассмотрено отдельно.

Пример 1

<HTML>
<HEAD>
<TITLE>Чтение текста из сервера с помощью AJAX</TITLE>
<SCRIPT SRC="ajax.js"></SCRIPT>
<SCRIPT>
serverAddr="http://zykov/data.txt";
serverPar="";
function handleStateChange()
{
myDiv=document.getElementById("div");
if(xmlHttp.readyState==1)
{
myDiv.innerHTML+="Состояние запроса:1 (подготовка к отправлению)";
try { myDiv.innerHTML+=", статус: "+xmlHttp.statusText+"<BR/>"; }
catch(e) { myDiv.innerHTML+="<BR/>"; }
}
else
{
if(xmlHttp.readyState==2)
{
myDiv.innerHTML+="Состояние запроса:2 (отправлен)";
try { myDiv.innerHTML+=", статус: "+xmlHttp.statusText+"<BR/>"; }
catch(e) { myDiv.innerHTML+="<BR/>"; }
}
else
{
if(xmlHttp.readyState==3)
{
myDiv.innerHTML+="Состояние запроса:3 (идет обмен)";
try { myDiv.innerHTML+=", статус: "+xmlHttp.statusText+"<BR/>"; }
catch(e) { myDiv.innerHTML+="<BR/>"; }
}
else
{
if(xmlHttp.readyState==4)
{
myDiv.innerHTML+="Состояние запроса:4 (обмен завершен)";
try { myDiv.innerHTML+=", статус: "+xmlHttp.statusText+"<BR/>"; }
catch(e) { myDiv.innerHTML+="<BR/>"; }
if(xmlHttp.status==200)
{
try
{
resp=xmlHttp.responseText;
myDiv.innerHTML+="<P>Сервер передал:"+resp;
}
catch(e) { alert("Ошибка чтения ответа: "+e.description); }
}
else { alert("Ошибка получения данных\n статус: "+xmlHttp.statusText);}
}
}
}
}
}
</SCRIPT>
</HEAD>
<BODY onLoad="process()">
<DIV ID="div" />
</BODY>
</HTML>
Оглавление

В примере 1 осуществляется чтение текстовых данных с локального сервера с помощью технологии AJAX: в переменную serverAddr заносится URL-адрес файла локального сервера ("http://zykov/data.txt"), который содержит строку "Привет, клиент!", а в переменную serverPar - пустая строка, поскольку в этом примере данные на сервер не передаются.
Поскольку технология AJAX требует использования Web-сервера, он должен быть запущен до выполнения примера.
Необходимо также отметить, что текстовые данные, если они являются кириллицей, должны быть сохранены на сервере в кодировке UTF-8.
Фукция handleStateChange() с помощью свойства readyState проверяет текущее состояние запроса и при его изменении выводит на экран в тэг <DIV> с помощью свойства innerHTML такие данные: номер состояния, его текстовое значение и статус. Текстовое значение статуса определяется с помощью свойства statusText объекта xmlHttp. Поскольку не для всех состояний запроса оно доступно, применяется конструкция try/catch(e).
Вывод всех состояний запроса сделан с учебной целью. Для получения данных достаточно проанализировать состояние 4 ("обемен данными завершен"), что и сделано в примере № 2.
Затем в состоянии 4 с помощью свойства status определяется, нормально ли закончился обмен данными с сервером. Если статус равен 200 (текстовое значение "OK"), что означает, что операции с сервером закончились успешно, делается попытка чтение данных, возвращенных сервером. Если ошибки нет - данные выводятся на экран, в виде свойства innerText тэга <DIV>.
В случае возникновения ошибки на экран выводится сообщение "Ошибка чтения ответа" с указанием дополнительных данных с помощью свойства e.description.
Если сервер передает другое значение статуса, что означает, что обмен произошел с ошибками, на экран выводится соответствующее сообщение с указанием статуса ошибки в текстовом виде.
При выполнении всех операций в примере 1 без ошибок на экран будут выведены следующие данные:

Состояние запроса:1 (подготовка к отправлению)
Состояние запроса:2 (отправлен), статус: OK
Состояние запроса:3 (идет обмен), статус: OK
Состояние запроса:4 (обмен завершен), статус: OK

Сервер передал: Привет, клиент!

Если необходимо осуществить чтение данных, находящихся на сервере в формате XML, например, из файла data.xml содержащего такие данные:

<?xml version="1.0" ?>
<name>Robert Sheckly</name>,

необходимо, помимо указания нового адреса файла - serverAddr="http://zykov/data.xml", заменить в функции handleStateChange() строку

resp=xmlHttp.responseText;

строкой

resp=xmlHttp.responseXML.getElementsByTagName("name")[0].firstChild.data;

Тогда вместо сообщения

Сервер передал: Привет, клиент!

появится сообщение

Сервер передал: Robert Sheckly

Оглавление

Пример 2

<HTML>
<HEAD>
<TITLE>Чтение случайных чисел из удаленного сервера с помощью AJAX/TITLE>
<SCRIPT>
serverAddr="http://www.random.org/integers/";
serverPar="?num=1&min=1&max=25&col=1&base=10&format=plain";
function handleStateChange()
{
myDiv=document.getElementById("div");
if(xmlHttp.readyState==4)
{
if(xmlHttp.status==200)
{
try { myDiv.innerHTML+=xmlHttp.responseText; }
catch(e) { alert("Ошибка чтения ответа: "+e.toStrintg()); }
}
else { alert("Ошибка получения данных\n статус: "+xmlHttp.statusText);}
}
}
</SCRIPT>
<SCRIPT SRC="ajax.js"></SCRIPT>
</HEAD>
<BODY onLoad="process()">
<DIV ID="div" />
</BODY>
</HTML>

В примере 2 осуществляется получение случайных чисел с удаленного сервера с помощью технологии AJAX: в переменную serverAddr заносится URL-адрес удаленного сервера ("http://www.random.org/integers/"), который снабжает клиентов настоящими случайными числами, а в переменную serverPar - строку "?num=1&min=1&max=20&col=1&base=10&format=plain", задающую значения следующих параметров запроса на получение случайных чисел:

В отличии от примера № 1 функция handleStateChange() не содержит кода, осуществляющего вывод на экран названия и статус различных состояний запроса.
В результате работы скрипта при каждом запросе на экран выводится одно случайное число в диапазоне от 1 до 25.
Оглавление

Индивидуальные задания

Отметить указанный в таблице объект и осуществить из заданной точки его движение с заданной функцией по указанному событию.

Объект(X,Y)Фукция F(x)КудаОтметкаДвижение
1СловоX=0;Y=4502x+5Вправо/вверхonDblclickonKeydown/Alt-1
2РисунокX=300;Y=40025cos(x)ВверхonClickonDblclick
3СсылкаX=450;Y=22040sin(3x)ВлевоonMouseoveronKeydown/ShiftLeft
4ТаблицаX=600;Y=400x*x/500Влево/вверхonMousemove>onKeydown/Shift-Z
5БукваX=200;Y=0exp(x/100)ВнизonContextmenuonKeydown/Ctrl-5
6РисунокX=10;Y=30030log(x+10)ВправоonClickonContextmenu
7СсылкаX=600;Y=20010tan(x)ВлевоonDblclickonKeydown/Tab-2
8СловоX=50;Y=500.001x*x+xВправо/внизonMousemoveonKeydown/W
9Кнопка X=500;Y=560sin(x*x)Влево/внизonContextmenuonClick
10БукваX=250;Y=45025cos(2x+1)ВверхonClickonContextmenu
11КнопкаX=350;Y=00.5exp(x/250)ВнизonDblclickonKeydown/1
12Ссылка X=75;Y=17550log(x+5)-50ВправоonMousemoveonContextmenu
13ТаблицаX=20;Y=4200.2x+45Вправо/вверхonMousemoveronKeydown/Atd>