sonyps4.ru

AJAX - Что это? Что такое AJAX.

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

Технология AJAX базируется на использовании объекта XMLHttpRequest(), который позволяет отправлять и получать информацию в различных форматах включая XML и HTML. Реализация технологии состоит из клиентской и серверной частей. Клиентская часть выполняется в браузере пользователя и пишется на JavaScript, а серверная выполняется на веб-сервере и пишется на любом языке веб-программирования: php, asp, perl и др.

Клиентский JavaScript-код - это основной код, выполняющий Ajax-приложение и обеспечивающий взаимодействие с сервером. Клиентская часть выполняет сбор информации для отправки запроса серверу, устанавливает соединение с сервером, посылает запрос, получает ответ и обрабатывает ответ сервера. Рассмотрим реализацию клиентской части подробней.

1. Создание объекта запроса XMLHttpRequest .
В Internet Explorer и других браузерах создание объекта XMLHttpRequest отличается. Во всех браузерах кроме Internet Explorer этот объект создается очень просто: xmlHttp = new XMLHttpRequest(); Браузер Internet Explorer для создания объекта запроса использует анализатор MSXML. Кроме того существует две разных версии MSXML. Универсальный метод создания объекта запроса XMLHttpRequest для всех браузеров выглядит следующим образом:


var xmlHttp=null;
try
{


}
catch (e)
{

try
{
xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");
}
catch (e)
{
xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
}
}

Создание объекта запроса происходит в строках xmlHttp = new XMLHttpRequest(); , xmlHttp=new ActiveXObject("Msxml2.XMLHTTP"); и xmlHttp=new ActiveXObject("Microsoft.XMLHTTP"); . Остальные строки обрабатывают ошибки.

2. Выполнение запроса .
Для выполнения запроса необходимо открыть соединение с сервером, установить функцию, которая выполниться после ответа сервера и передать запрос.

Чтобы указать функцию которая будет обрабатывать ответ, необходимо свойству onreadystatechange присвоить имя JavaScript функции: xmlHttp.onreadystatechange = MyFunc; . Причем имя функции указывается без скобок.

Чтобы открыть соединение с сервером необходимо вызвать функцию open() . Эта функция имеет три обязательных параметра:

  • метод запроса HTTP - обычно используют "GET" или "POST" , но можно использовать любой другой метод в соответствии с HTTP стандартами ;
  • url запроса - адрес скрипта на сервере, который обрабатывает запрос;
  • асинхронность запроса - TRUE или FALSE, если TRUE, то запрос асинхронный и пользователь сможет продолжать работу со страницей.

Для отправки запроса необходимо вызвать метод send() , параметром которого могут быть любые данные, которые вы хотите отправить на сервер. Данные должны быть сформированы в строку запроса param1=1¶m2=2¶m3=3 .

Если данные отправляются методом POST, то необходимо изменить MIME-тип запроса: xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); .

Выполнение запроса с использованием метода GET :

/*Устанавливаем соединение*/
xmlHttp.open("GET", "example.php?param1=1¶m2=2", true);
/*Указываем функцию*/

/*Отправляем запрос*/
xmlHttp.send(null);

И с использование метода POST :

/*Устанавливаем соединение*/
xmlHttp.open("POST", "example.php", true);
/*Меняем MIME-тип*/
xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
/*Указываем функцию*/
xmlHttp.onreadystatechange = MyFunc;
/*Отправляем запрос*/
xmlHttp.send("param1=1¶m2=2");

3. Обработка ответа сервера .
Отправляя запрос, мы указали имя функции, обрабатывающей ответ сервера: xmlHttp.onreadystatechange = MyFunc; . Для начала, эта функция должна проверять статус запроса. Это можно сделать с помощью свойства readyState . Если xmlHttp.readyState = 4 , то ответ от сервера получен и можно приступать к его обработке. Далее необходимо проверить статус HTTP-ответа с помощью свойства status . Если xmlHttp.status = 200 значит все в порядке и можно продолжить обработку данных. Получить доступ к данным можно с помощью свойств responseText - в виде текста, либо responseXML - в виде объекта XMLDocument.

Полный пример работы Ajax-приложения:


/*переменная для хранения объекта запроса*/
var xmlHttp=null;
/*создание объекта запроса*/
function createRequest()
{
try{
//создаем объект запроса для Firefox, Opera, Safari
xmlHttp = new XMLHttpRequest();
} catch(e){
//создаем объект запроса для Internet Explorer
try{
xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
} catch(e){
try{
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
} catch(e){
xmlHttp = null;
}
}
}

If(xmlHttp == null)alert("Браузер не поддерживает AJAX!");
}

/*отправка запроса*/
function sendRequest()
{
/*получаем объект запроса*/
createRequest();
/*Устанавливаем соединение*/
xmlHttp.open("GET", "ajax.php?param1=1¶m2=2", true);
/*Указываем функцию*/
xmlHttp.onreadystatechange = MyFunc;
/*Отправляем запрос*/
xmlHttp.send(null);
}

/*обрабатываем ответ*/
function MyFunc()
{
if(xmlHttp.readyState == 4) {
if (xmlHttp.status == 200) {
alert(xmlHttp.responseText);
} else {
alert("Ошибка обработки запроса!");
}
}
}

Серверная часть может быть написана на чем угодно. Возвращаемое значение xmlHttp.responseText формируется стандартным выводом. Пример серверной части на php:

Попробуйте пример в действии:

И в дополнение некоторые справочные материалы по объекту XMLHttpRequest :
Методы класса XMLHttpRequest


Свойства класса XMLHttpRequest

Все начинающие web-мастера рано или поздно сталкиваются с проблемой динамического изменения данных на HTML странице, причем без перезагрузки этой самой страницы. И на помощь приходит, конечно же, JavaScript, но он не умеет обращаться к серверу и получать данные без перезагрузки страницы, но зато - это умеет AJAX , именно о нем мы сегодня и поговорим.

Примечание. Если Вы не знаете основы JavaScript, и не можете понять простой код на JavaScript, советую, для начала, прочитать вот эти статьи "JavaScript для начинающих – Простые примеры " и "JavaScript – Пример расширения формы регистрации " ,так как без знаний JavaScript учить AJAX бессмысленно!

Что такое AJAX?

AJAX (Asynchronous JavaScript and XML ) - асинхронный JavaScript и XML, это механизм взаимодействия с сервером, посредствам которого происходит обмен данными с этим сервером, не перезагружая всю страницу целиком. Запрос на AJAX может быть не только асинхронный, но и просто синхронным, но такие запросы используются редко. Так как при таких запросах браузер зависает, до того момента пока не будет получен ответ с сервера, в отличие от асинхронного запроса, при котором посылается запрос и пользователь может делать на странице все что угодно, а когда будет получен ответ от сервера, сработает обработчик и появятся изменения на странице. Как посылать синхронные и асинхронные запросы научимся ниже в примерах.

Для чего нужен AJAX?

И первое что приходит на ум это, конечно же, быстрый и удобный интерфейс для пользователя . Другими словами, пользователь любит, когда у него быстро все работает и не нужно делать лишних телодвижений, к тому же, чтобы это все красиво выглядело, JavaScript и AJAX с этим отлично справляются.

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

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

Недостатки AJAX

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

Во-вторых, можно отметить то, что при использовании ajax полученные данные не индексируются поисковыми системами и, конечно же, нельзя поставить закладки в браузере.

Пример использования AJAX

Хватит теории, перейдем к практике. Сразу скажу, что ajax - это не сложно, и если Вы разобрались с JavaScript, то разобраться с ajax будет очень просто, даже легче чем с JavaScript!

И начну я с того, что весь ajax строится на объекте XMLHttpRequest , у которого есть несколько свойств и несколько методов, которые легко освоить и запомнить. Объект XMLHttpRequest - это своего рода мини-браузер, от имени которого и будет посылаться запрос к серверному скрипту.

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

Var request = new XMLHttpRequest();

где, в переменной request и будет храниться наш объект.

Но если Ваше приложение могут использовать и в старых браузерах, то лучше использовать универсальный способ создания данного объекта, мне, например, нравится вот такой способ:

Function getXmlHttpRequest() { if (window.XMLHttpRequest) { try { return new XMLHttpRequest(); } catch (e){} } else if (window.ActiveXObject) { try { return new ActiveXObject("Msxml2.XMLHTTP"); } catch (e){} try { return new ActiveXObject("Microsoft.XMLHTTP"); } catch (e){} } return null; }

Для создания объекта XMLHttpRequest мы просто вызовем функцию getXmlHttpRequest, которая вернет нам нужный объект.

Объект создан, теперь можно писать код на JavaScript, который будет формировать запрос на сервер, и обрабатывать данные, полученные с сервера.

Для того чтобы наш урок прошел полноценно, нам потребуется небольшой серверный скрипт, я буду использовать серверный язык программирования PHP, и наш скрипт будет просто возвращать текущие время на сервере. Назовем его mytime.php, его код:

Код mytime.php:

Здесь я думаю все понятно, мы проверяем параметр, пришедший к нам методом GET, т.е. MyTime, и если параметр действительно к нам пришел, то возвращаем текущие время на сервере. Советую при разработке ajax приложения на серверном скрипте делать больше проверок, так как ajax запрос можно подделать. Можно делать вот такие проверки, например:

  • можно дополнительно посылать заголовок X-REQUESTED-WITH , а на серверном обработчике проверять его;
  • также добавить проверку реферера, т.е. откуда пришел запрос;
  • еще можно осуществлять проверку с помощью сессий.

Код index.php:

//функция создания объекта XMLHttpRequest function getXmlHttpRequest(){ if (window.XMLHttpRequest) { try { return new XMLHttpRequest(); } catch (e){} } else if (window.ActiveXObject) { try { return new ActiveXObject("Msxml2.XMLHTTP"); } catch (e){} try { return new ActiveXObject("Microsoft.XMLHTTP"); } catch (e){} } return null; } function serverTime(){ // Объект XMLHttpRequest var request = getXmlHttpRequest(); /*свойство onreadystatechange это обработчик события, которое реагирует на любое изменения данного объекта*/ request.onreadystatechange = function (){ /*свойство readyState - состояние объекта 0 - не инициализирован 1 - открыт, 2 - отправка данных, 3 - получение данных, 4 - данные загружены рекомендую использовать только 4*/ if (request.readyState == 4) { /*свойство status это HTTP-статус ответа: 200-OK, 404-Not Found*/ if (request.status == 200){ var result = document.getElementById("MyId"); // Чтение ответа result.firstChild.nodeValue = request.responseText; // Вывод на экран } else document.write("Произошла ошибка. Обнови страничку"); } } // Адрес серверного скрипта var url = "mytime.php?MyTime"; /* Запрос на сервер, true означает что это асинхронный запрос если было бы false, то это синхронный запрос*/ request.open("GET", url, true); request.setRequestHeader("Content-type", "charset=utf8"); request.send(null); // посыл данных }

Вот два файла (mytime.php и index.php ), с помощью которых Вы легко можете проверить работу ajax, код этих файлов представлен выше.

Кстати, в вышеуказанном примере мы использовали передачу данных методом GET, есть много способов передачи данных и все основные данные передаются с помощью метода POST. Давайте переделаем нашу функцию serverTime, чтобы она передавала данные методом post, это сделать очень легко, так как поменять нужно всего несколько строк.

Код функции serverTime с передачей параметров методом post:

Function serverTime(){ var request = getXmlHttpRequest(); request.onreadystatechange = function (){ if (request.readyState == 4) { if (request.status == 200){ var result = document.getElementById("MyId"); result.firstChild.nodeValue = request.responseText; } else document.write("Произошла ошибка. Обнови страничку"); } } var url = "mytime2.php";//изменим адрес серверного обработчика var data = "MyTime=1";//задаем параметры request.open("POST", url, true); // указываем метод post //посылаем два заголовка: тип данных и размер данных request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); request.setRequestHeader("Content-Length", data.length); request.send(data); // посыл данных, вместо null вставляем переменную с параметрами }

Не забудьте изменить серверный обработчик, чтобы он проверял данные пришедшие методом post. Измените строку isset($_GET["MyTime"] на isset($_POST["MyTime"] и все будет работать точно так же, как и с помощью GET.

Как Вы заметили, ajax совсем не сложная штучка, хотя это только основы, но все равно если Вы разобрались, например, с JavaScript, то освоить ajax будет не проблема.

В сегодняшнем уроке мы рассмотрели только основы, в ajax есть еще что изучать (хотя не много), например, передача сложных данных и т.д., но надеюсь, этот урок Вам помог узнать, что же такое ajax и в следующих уроках мы продолжим изучать этот механизм взаимодействия с сервером!

AJAX - Что это?

Когда существующих возможностей становиться мало, а совершенствовать существующее уже некуда, тогда и происходит технологический прорыв. Таким прорывом и есть AJAX (Asynchronous JavaScript and XML) - подход к построению пользовательских интерфейсов веб-приложений, при котором web-страница, не перезагружаясь, сама догружает нужные пользователю данные. AJAX - один из компонентов концепции DHTML.

Что же дает нам эта технология. В настоящее время разработка WEB приложений стремится к разграничению клиентской части и серверной, этим и обуславливается повсеместное использование шаблонов, таких как Smarty и XSLT. Сейчас проекты становятся сложнее, и переплетать между собой различные технологии становиться слишком дорого для времени разработчика. Так, например, все стили форматирования выносятся в CSS или в XSL файлы, HTML или XML данные хранятся в других разделах, серверные обработчики в третьих, базы данных в четвертых. И если еще 5-6 лет назад практически везде можно было увидеть переплетение всего этого в одном файле, то сейчас это все чаще становиться редкостью.

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

Возникает необходимость в разграничении работы. Так, например, дизайнер будет делать свою работу, верстальщик свою, программист свою, и при этом никто друг другу мешать не будет. В итоге каждому участнику проекта достаточно будет знать только те данные, с которыми ему придется работать. В таком случае производительность группы и качество проекта повышается в разы. В настоящее время эта проблема с успехом решается путем использования шаблонов, однако это тоже создает определенные трудности, так как чтобы, скажем, подключить Smarty, необходимо подключить программный модуль обработки шаблонов, и четко связать со структурой проекта. А это далеко не всегда возможно и требует определенных затрат. Немного проще при использовании связки XML + XSL, так как они предоставляют больше возможностей, однако это альтернатива, не более. А что если посмотреть в сторону чего-то радикально нового, что позволяло бы объединить все лучше, используя возможности того, что есть? Попробуйте представить JavaScript, который обладает всем возможностями PHP или Perl, включая работу с графикой и базами данных, который имеет гораздо более удобную расширяемость и практичность, и к тому же кросс-платформен.

Так что же такое AJAX? Впервые об Ajax заговорили после появления в феврале 2005-го года статьи Джесси Джеймса Гарретта (Jesse James Garrett) "Новый подход к веб-приложениям" . Ajax - это не самостоятельная технология. Это идея, которая базируется на двух основных принципах.

Использование DHTML для динамичного изменения содержания страницы.

Использование XMLHttpRequest для обращения к серверу "на лету".

Использование этих двух подходов позволяет создавать намного более удобные WEB-интерфейсы пользователя на тех страницах сайтов, где необходимо активное взаимодействие с пользователем. Использование Ajax стало наиболее популярно после того, как компания Google начала активно использовать его при создании своих сайтов, таких как Gmail, Google maps и Google suggest. Создание этих сайтов подтвердило эффективность использования данного подхода.

Итак подробнее: если взять классическую модель WEB-приложения:

Клиент, набирая в строке поиска адрес интересующего его ресурса, попадая на сервер, делает к нему запрос. Сервер производит вычисления в соответствии с запросом, обращается к базе данных и так далее, после чего полученные данные идут клиенту и, в случае необходимости подставляются в шаблоны и обрабатываются браузером. Результатом является страница, которую мы видим, и которую 80% населения страны находящейся в WEB называют Интернетом. Это классическая модель, которая успела себя зарекомендовать и заслужить себе почетное место под солнцем. Это самая простая модель взаимодействия и, как следствие, самая распространенная. Однако ее все чаще становиться недостаточно. Представьте себе, on-line игру "Морской бой", в которую играют два закоренелых друга - житель ЮАР и житель Японии. Как с помощью такой модели сделать их игру максимально приятной? В любом случае данные потопленных кораблей будут хранится на сервере, и что бы проверить не походил ли оппонент, необходим будет каждый раз обновлять страницу и подгущать устаревшие данные. "Но ведь люди придумали кэширование" - скажете вы и будете абсолютно правы, но легче от этого не становиться. Кэширование всего лишь ускорит время взаимодействия с сервером, но не избавит от необходимости перезагружать страницу. Как вариант можно поставить определенное время самообновления, но и в этом случае страница будет перезагружаться полностью.

Теперь посмотрим на модель взаимодействия AJAX:

Последовательность действий клиента сохраняется и он, скорее всего не поймет того, что будет происходить, а слово AJAX будет ассоциироваться только с названием футбольного клуба. Но на стороне сервера все выглядит иначе.

При обращении к серверу, генерируется страница, которая будет отображаться пользователю, и предлагать ему совершить интересующую его последовательность действий. При сознательном (хотя и не обязательно) выборе клиента, его запрос будет обращаться к AJAX модулю, который и будет производить все интересующие его вычисления и работу с сервером как таковым. Но в чем же новшество? Основное отличие в том что этот метод дает нам возможность динамически обращаться к серверу и выполнять интересующие нас действия. Например, нам нужно выполнить обращение к базе данных и получить интересующие нас данные которые затем будем использовать. Данные мы будем хранить в XML файле который будет формироваться динамически, таким образом:

Создаем новый объект JavaScript:

Var req = new ActiveXObject("Microsoft.XMLHTTP"); (для IE) var req = new XMLHttpRequest(); (Для всего остального)

Затем пишем функцию использующий этот объект

Var req; function loadXMLDoc(url) { // branch for native XMLHttpRequest object if (window.XMLHttpRequest) { req = new XMLHttpRequest(); req.onreadystatechange = processReqChange; req.open("GET", url, true); req.send(null); // branch for IE/Windows ActiveX version } else if (window.ActiveXObject) { req = new ActiveXObject("Microsoft.XMLHTTP"); if (req) { req.onreadystatechange = processReqChange; req.open("GET", url, true); req.send(); } } }

Теле HTML файла пишем скрипт, который будет:

Function checkName(input, response) { if (response != ""){ // Response mode message = document.getElementById("nameCheckFailed"); if (response == "1"){ message.className = "error"; }else{ message.className = "hidden"; } }else{ // Input mode url = "http://localhost/xml/checkUserName.php?q=" \\ + input; loadXMLDoc(url); } }

В файле localhost/xml/checkUserName.php мы обрабатываем данные, полученные из командной строки в данном случае в переменной q. А результат сохраняем в XML структуре, которую храним в этом же файле. Так мы можем получить и обработать данные, полученные из БД, или что-нибудь другое необходимое нам. К тому же сервер будет обрабатывать только те данные, которые нам необходимо обновить, а не всю страницу в случае ее перезагрузки.

Теперь вернемся к двум друзьям - любителям морского боя: ввиду появления данного новшества, мы можем сделать следующее: поставить проверку в течении каждых трех секунд XML файла данная проверка подразумевает под собой проверку базы данных на предмет новой записи, то есть - сделанного оппонентом хода. Если ход был сделан, страница без перезагрузки топит корабли, тем самым, портя настроение участникам водных баталий. Данная функциональность достигается элементарным использованием Javascript и таблиц стилей. Этот пример достаточно наглядный, однако далеко не полный, применение данной технологии гораздо существенней.

Однако не все так просто. Давайте теперь рассмотрим отрицательные черты.

Во-первых - мы можем передавать данные только методом GET, соответственно большие объемы данных придется оставить в покое. Данная проблема уже не раз поднималась в разных источниках, но господа, есть ведь Сookies, которые вполне приемлемы в случаях передачи больших данных, чем может вместить в себя GET запрос, а Javascript в свою очередь имеет функции для работы с ними.

Вторая проблема - кросс-браузерность. Объект XMLHttpRequest еще не является частью какого-либо стандарта (хотя нечто подобное уже было предложено в спецификации W3C DOM Level 3 Load and Save). Поэтому существует два отличных друг от друга метода вызова этого объекта в коде скрипта. В Internet Explorer объект ActiveX вызывается так:

Var req = new ActiveXObject("Microsoft.XMLHTTP");

В Mozilla и Safari это делается проще (так как там это объект, встроенный в JavaScript):

Var req = new XMLHttpRequest();

Все современные браузеры поддерживают данный объект и проблемы возникнут только у 1,8% пользователей (согласно данными статистики компании SpyLog), которые пользуются очень старыми версиями браузеров, не поддерживающими этот объект.

И, наконец, защищенность. На этом остановимся поподробнее. Основная проблема заключается в том, что все данные и исходный код JavaScript функций можно увидеть путем просмотра исходного кода страницы, соответственно злоумышленник может проследить логику выполнения запросов и при определенном стечении обстоятельств выполнить необходимый ему набор команд. Это не играет особой роли, когда у нас идет простое сопоставление данных, но что делать в более сложных ситуациях, например при авторизации, и как в таком случае передавать пароли. Как уже было сказано выше, на помощь приходят Cookies. Необходимые данные можно пересылать с их помощью, так же их и обрабатывать. Возьмем пример, в котором пользователь будет проходить аутентификацию с помощью технологии которой посвящена статья.

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

После того как пользователь ввел данные и нажал кнопку Submit его пароль заноситься в Cookies, а имя пользователя передается открыто - ссылкой например http://www.mubestajax.com/ajax.php?login=pupkin при получении данных сервер, в первую очередь проводит сверку полученных данных. Так как значения которые мы генерировали с начала работы сервера а затем передавали их глобальным переменным сервера и cookies должны совпадать, то при проверке целостности переданных данных в случае несовпадения программа перестает работать. Если же все прошло хорошо, то извлекаются все необходимые данные и проводятся необходимые вычисления и работы. Такой способ защиты достаточно прост и эффективен. Но для больших проектов он не подойдет.

Когда на первый план выходит безопасность, лучше использовать более сложные и надежные решения. Но в большинстве случаев данных мер предосторожности будет более чем достаточно, так как использование более сложных модулей влечет за собой использование технологий которые не всегда входят в состав стандартного программного обеспечения современных серверов, основная черта которых - простота. Именно по этому такие технологии как MySQL и PHP получили очень широкое распространение, т.к. они обеспечивают простоту работы при своей небольшой ресурсоемкости и достаточной надежности. А к рамках данного программного обеспечения как нельзя лучше подойдет решение предложенное выше.

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

AJAX расшифровывается как Asynchronous Javascript And XML, что означает Асинхронный JavaScript и XML. AJAX позволяет обновлять данные HTML-страницы без полной её перезагрузки. Кроме этого технология позволяет работать с интернет-страницами асинхронно. То есть пока JavaScript взаимодействует с Web-сервером, пользователь может продолжать работать с web-страницей.

Примером использования технологии AJAX является Google Suggest . Работа Google Suggest заключается в том, что пока вы вводите слово или фразу для поиска, JavaScript обращается к базе данных Google и запрашивает у неё 10 самых популярных запросов, начинающихся с тех же букв. И затем выводит этот список без перезагрузки страницы.

Для рассмотрения принципов работы технологии AJAX, реализуем на своем сайте механизм подобный Google Suggest. Допустим, у нас есть сайт туроператора. На сайте есть поле поиска предложений по названию страны. Добавим к этому полю раскрывающийся список с автозаполнением по введенным буквам. Приступим к решению этой задачи. Сразу оговорюсь, что для реализации этой задачи необходимо знание HTML и немного JavaScript(знатоком быть не обязательно). В качестве серверного языка будет использован php.

Для начала создадим форму поиска. Для этого на вашем web-сервере создайте файл index.html, откройте его при помощи любого текстового редактора и введите следующий html-код.




Поиск предложений.





Отдых на море

Поиск предложений:








В этом листинге мы создали форму поиска с полем для ввода текста и кнопкой отправки, и создаем слой div для вывода результатов. К данной странице так же прикрепляется файл ajax.js, который будет содержать функции JavaScript.

Далее напишем функции JavaScript, которые будут посылать запросы серверу и обновлять страничку. Для того чтобы не приходилось перегружать html-документ полностью нам и понадобиться технология Ajax. Итак, приступим. Создайте файл ajax.js, поместите его в ту же папку, что и index.html, и откройте его в текстовом редакторе.

Для начала необходимо создать объект, который будет передавать запросы серверу и принимать ответы. В разных браузерах этот объект создается по разному. Мы напишем универсальную функцию, которая должна работать в разных браузерах. Добавьте в файл ajax.js следующий код JavaScript.

/*переменная для хранения объекта запроса*/
var request;
/*функция создания объекта запроса*/
function CreateRequest()
{
var request=null;
try
{
//создаем объект запроса для Firefox, Opera, Safari
request = new XMLHttpRequest();
}
catch (e)
{
//создаем объект запроса для Internet Explorer
try
{ request=new ActiveXObject("Msxml2.XMLHTTP");
}
catch (e)
{
request=new ActiveXObject("Microsoft.XMLHTTP");
}
}
return request;
}

Выводить список результатов необходимо при каждом изменении в поле поиска. Для этого воспользуемся обработчиком событий JavaScript. Определять изменения будем при каждом событии клавиатуры keyup . Для этого в наш HTML-код файла index.html в строке, где создается поле поиска с именем country , добавим атрибут onkeyup="KeyPress(this.value)" :

Т. е. при нажатии любой клавиши будет вызываться функция JavaScript KeyPress() , в которую в качестве параметра передаются символы, введенные в строку поиска. Функция KeyPress() должна выполнить следующие задачи:

  • Создать новый объект запроса посредством вызова функции CreateRequest();
  • Сформировать URL-адрес, к которому необходимо подключиться для получения результатов;
  • Настроить объект запроса для установки связи с сервером;
  • Отправить запрос серверу.

Приступим к созданию функции KeyPress() . Для создания нового объекта запроса нам просто необходимо переменной request присвоить значение, возвращаемое ранее созданной функцией CreateRequest() . И для надежности проверим переменную request . Если она равна NULL , то объект запроса создать не удалось. Вот так будет выглядеть код JavaScript для решения данной задачи:

Function KeyPress(term) {
request=CreateRequest();

if(request==null)
{
return;
}
}

Далее необходимо указать объекту запроса request какая функция JavaScript будет обрабатывать ответ сервера. Для этого необходимо свойству onreadystatechange присвоить имя соответствующей функции. Данное свойство указывает браузеру, какую функцию запускать при каждом изменении состояния готовности запроса. У нас обработкой ответа будет заниматься функция LoadResults() . Добавьте в функцию следующую строку: request.onreadystatechange = LoadResults; . Отметим, что после названия функции нет скобок.

Затем займемся настройкой подключения. Для этого сначала необходимо указать объекту, куда передавать этот запрос. Сформируем URL-адрес сценария, который будет вычислять результаты, и присвоим его переменной url . Допустим, за вычисление результатов на стороне сервера у нас будет отвечать php-скрипт country.php . Тогда наш URL-адрес будет выглядеть следующим образом: var url = "country.php" + "?s=" + encodeURIComponent(term) + "&sid=" + Math.random(); , где с переменной s передаются введенные в поле поиска символы, а sid присваивается случайное число, чтобы браузер не кэшировал страницу. Добавьте эту строчку в тело функции KeyPress() .

Далее необходимо инициализировать подключение с помощью метода open("GET", url, true) объекта request . Этот метод имеет три параметра. Параметр "GET" указывает, как отправить данные серверу. Мы используем метод GET , потому что введенные символы в строку поиска передаются серверному сценарию через url-адрес. Во второй параметре указывается url-адрес серверного сценария. У нас url-адрес храниться в переменной url , поэтому во втором параметре мы указываем эту переменную. Третий параметр может иметь два значения: true - асинхронный режим и false - синхронный режим. Наше приложение будет работать в асинхронном режиме, поэтому указываем true . После инициализации подключения, необходимо создать подключение и запросить результаты. Для этого просто необходимо вызвать функцию send(null) объекта request . Параметр null указывает, что запрос не содержит данных.

После внесения всех изменений функция KeyPress(this.value) примет следующий вид:

Function KeyPress(term)
{
/*создаем новый объект запроса*/
request=CreateRequest();
/*если не удалось создать объект запроса, то заканчиваем выполнение функции*/
if(request==null)
{
return;
}
/*формируем url-адрес*/
var url = "country.php" + "?s=" + encodeURIComponent(term) + "&sid=" + Math.random();
/*настраиваем объект запроса для установки связи*/
request.onreadystatechange = LoadResults;
request.open("GET", url, true);
/*отправляем запрос серверу*/
request.send(null);
}

Итак, соединение установлено, запрос отправлен, сервер обрабатывает данные и возвращает результат. Далее необходимо получить ответ, обработать и вывести результаты на web-страницу. Всем этим будет заниматься функция LoadResults() , которая будет вызываться при каждом изменении статуса готовности запроса. Рассмотрим, как должна работать эта функция.

Для начала необходимо проверить текущее состояние готовности. Статус готовности хранит свойство объекта запроса readyState . При завершении обработки запроса состояние готовности равно 4. Т.е. если request.readyState == 4 , то можно обрабатывать ответ:

Function LoadResults()
{


/*обрабатываем ответ*/
}
}

Function LoadResults()
{
/*Проверяем состояние готовности*/
if (request.readyState == 4){
/*Проверяем статус запроса*/
if (request.status == 200){
/*все в порядке, обрабатываем ответ*/
}
}
}

Если проверка состояния и статуса запроса закончилась успешно, то можно приступать к обработке данных, полученных от сервера. Получить данные можно двумя способами: request.responseText - получение данных в виде текста, либо request.responseXML - получение данных в виде объекта XMLDocument. Допустим, у нас сервер передает ответ в виде текстового списка стран через запятую. Тогда получаем данные: var answer = request.responseText . Далее обрабатываем данные и выводим их в слой с id="searchresults" .

Я не буду вдаваться в подробности обработки данных, а просто приведу код функции с комментариями:

Function LoadResults()
{
/*Проверяем состояние готовности*/
if (request.readyState == 4){
/*Проверяем статус запроса*/
if (request.status == 200){
//делаем слой searchresults видимым
ShowDiv("searchresults");
//очищаем результаты
ClearResults();
//получаем данные
var answer = request.responseText;
//преобразуем строку текста в массив
var array = answer.split(",");
//определяем размер массива
var count = array.length;
//находим слой searchresults

//создаем таблицу в объектной модели документа
var tbl = document.createElement("table");
var tblbody = document.createElement("tbody");
var tblRow, tblCell, tblNode;
//перебираем все элементы массива array
for(var i = 0; i {
var text = array[i];
//создаем строки таблицы и добавляем в ее тело
tblRow = document.createElement("tr");
tblCell = document.createElement("td");
//задаем атрибуты и функции ячеек
tblCell.onmouseover = function(){this.className="mouseOver";};
tblCell.onmouseout = function(){this.className="mouseOut";};
tblCell.setAttribute("border", "0");
tblCell.onclick = function(){Replace(this);};
tblNode = document.createTextNode(text);
tblCell.appendChild(tblNode);
tblRow.appendChild(tblCell);
tblbody.appendChild(tblRow);
}
//добавляем в таблицу ее тело
tbl.appendChild(tblbody);
//помещаем таблицу в слой
div.appendChild(tbl);
}
}
}

И еще пару вспомогательных функций JavaScript для вывода результатов на экран:

/*делаем слой с результатами видимым*/
function ShowDiv(id)
{
if (document.layers) document.layers.visibility="show";
else document.getElementById(id).style.visibility="visible";
}

/*делаем слой с результатами не видимым*/
function HideDiv(id)
{
if (document.layers) document.layers.visibility="hide";
else document.getElementById(id).style.visibility="hidden";
}

/*очистка результатов*/
function ClearResults()
{
/* Удаление существующих строк из таблицы результатов
var div = document.getElementById("searchresults");
var counter = div.childNodes.length;
for(var i = counter-1; i >= 0; i--)
{
div.removeChild(div.childNodes[i]);
}
}

/*Заменяем значение в поле ввода значением, выбранным щелчком мыши*/
function Replace(tblCell)
{
var inputbox = document.getElementById("country");
inputbox.value = tblCell.firstChild.nodeValue;
ClearResults();
HideDiv("searchresults");
}

Так же в наш html-файл index.html между тегами и добавьте следующие правила CSS:


.mouseOut{ background: #ffffff; color: #0000000; }
.mouseOver{ background: #ccccff; color: #0000000; }
table {width:250px }

На этом все. В данной статье мы рассмотрели основы работы технологии Ajax на примере.

AJAX: С чего начать

В этой статье рассмотрены основные принципы работы AJAX и даны два простых примера, использующих эту технологию.

1 Что такое AJAX?
2 Шаг 1 - Как послать HTTP запрос
3 Шаг 2 - Обрабатываем HTTP ответ
4 Шаг 3 - Простой пример
5 Шаг 4 - Работа с XML ответом

Что такое AJAX?

Ajax означает Асинхронный JavaScript и XML. В основе технологии лежит использование нестандартного объекта XMLHttpRequest(), необходимого для взаимодействия со скриптами на стороне сервера. Объект может как отправлять, так и получать информацию в различных форматах включая XML, HTML и даже текстовые файлы. Самое привлекательное в Ajax - это его асинхронный принцип работы. С помощью этой технологии можно осуществлять взаимодействие с сервером без необходимости перезагрузки страницы. Это позволяет обновлять содержимое страницы частично, в зависимости от действий пользователя.

Две особенности, которые мы рассмотрим:

* Отправление запросов серверу без перезагрузки страницы
* Работа с XML документами

Шаг 1 - Как послать HTTP запрос

Для того, чтобы послать HTTP запрос на сервер используя JavaScript, вам необходим экземпляр класса, который позволит это сделать. Такой класс впервые был введен в Internet Explorer как объект ActiveX, называемый XMLHTTP. Позже в Mozilla, Safari и другие броузеры был введен класс XMLHttpRequest, который поддерживал методы и свойства изначального объекта ActiveX от Microsoft.

В результате, чтобы создать кросс-броузерный объект требуемого класса, вы можете сделать следующее:

if (window.XMLHttpRequest) { // Mozilla, Safari, ...



}

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

Некоторые версии некоторых броузеров Mozilla не будут корректно работать, если ответ сервера не содержит заголовка XML mime-type. Чтобы решить эту проблему вы можете использовать вызовы дополнительных методов для переопределения заголовка полученного от сервера, если он отличен от text/xml.

http_request = new XMLHttpRequest();

Далее вам необходимо решить, что вы будете делать после получения ответа сервера. На этом этапе вам необходимо указать объекту, какая JavaScript функция будет обрабатывать ответ. Это делается путем присваивания свойству onreadystatechange имени JavaScript функции, которую вы собираетесь использовать:

Заметьте, что после названия функции нет скобок и не указано параметров, потому что вы просто присваиваете ссылку на функцию, а не вызываете ее. К тому же, вместо указания имени функции, вы можете использовать возможность JavaScript объявлять функции на лету (так называемые «анонимные функции») и указывать действия, которые тотчас же будут обрабатывать ответ:

http_request.onreadystatechange = function(){
// какой-нибудь код
};

http_request.open("GET", "http://www.example.org/some.file", true);
http_request.send(null);

* Первый параметр вызова функции open() - метод запроса HTTP (GET, POST, HEAD или любой другой метод, который вы хотите использовать). Используйте методы в соответствии с HTTP стандартами; иначе некоторые броузеры (такие как Firefox) могут не обработать запрос. Информация о допустимых HTTP запросах доступна по адресу спецификации W3C
* Второй параметр - URL запрашиваемой страницы. Из соображений безопасности вы не можете запрашивать страницы сторонних доменов. Убедитесь, что вы используете одинаковое доменное имя на всех страницах, иначе вы получите ошибку "доступ запрещен" при вызове функции open(). Типичной ошибкой при доступе к сайту через site.ru является подача запросов на www.site.ru.
* Третий параметр указывает, является ли запрос асинхронным. Если он TRUE, то выполнение JavaScript продолжится во время ожидания ответа сервера. В этом и заключается асинхронность технологии.

Параметром метода send() могут быть любые данные, которые вы хотите послать на сервер. Данные должны быть сформированы в строку запроса:

name=value&anothername=othervalue&so=on

Заметьте, что если вы хотите отправить данные методом POST, вы должны изменить MIME-тип запроса с помощью следующей строки:

http_request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");

Иначе сервер проигнорирует данные отправленные методом POST.

Шаг 2 - Обрабатываем HTTP ответ

Отправляя запрос, вы указали имя функции JavaScript, обрабатывающей ответ.

http_request.onreadystatechange = nameOfTheFunction;

Давайте посмотрим, что эта функция должна делать. Во-первых, функция должна проверять статус запроса. Если значение переменной статуса 4, то это означает, что ответ от сервера получен и его можно обрабатывать.

if (http_request.readyState == 4) {
// все в порядке, ответ получен
} else {
// все еще не готово
}

Полный список значений кодов readyState такой:

* 0 (uninitialized)
* 1 (loading)
* 2 (loaded)
* 3 (interactive)
* 4 (complete)

Следующее, что нужно проверить - это статус HTTP-ответа. Все возможные коды можно посмотреть на сайте W3C . Для наших целей нам интересен только код ответа 200 OK.

if (http_request.status == 200) {
// великолепно!
} else {
// с запросом возникли проблемы,
// например, ответ может быть 404 (Не найдено)
// или 500 (Внутренняя ошибка сервера)
}

Теперь, после проверки состояния запроса и статуса HTTP-ответа, вы можете делать с данными, полученными от сервера, все что угодно. Есть два способа получить доступ к данным:

* http_request.responseText – возвращает ответ сервера в виде строки текста.
* http_request.responseXML – возвращает ответ сервера в виде объекта XMLDocument, который вы можете обходить используя функции JavaScript DOM

Шаг 3 - Простой пример

Давайте соберем все вместе и сделаем простой пример HTTP-запроса. Наш JavaScript запросит HTML документ test.html, который содержит текст "I"m a test." и выведет содержимое файла в диалоговом окне.


function makeRequest(url) {
var http_request = false;
if (window.XMLHttpRequest) { // Mozilla, Safari, ...
http_request = new XMLHttpRequest();
if (http_request.overrideMimeType) {
http_request.overrideMimeType("text/xml");
// Читайте ниже об этой строке
}
} else if (window.ActiveXObject) { // IE
try {
http_request = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
http_request = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e) {}
}
}
if (!http_request) {
alert("Не вышло:(Невозможно создать экземпляр класса XMLHTTP ");
return false;
}
http_request.onreadystatechange = function() { alertContents(http_request); };
http_request.open("GET", url, true);
http_request.send(null);
}
function alertContents(http_request) {



} else {

}
}
}


Сделать запрос

В этом примере:

* Пользователь нажимает на ссылку "Сделать запрос" в броузере;
* Это вызывает функцию makeRequest() с параметром test.html - именем HTML файла;
* Посылается запрос, после чего (onreadystatechange) выполнение передается alertContents();
* alertContents() проверяет получен ли ответ и все ли с ним в порядке, после чего содержимое файла test.html выводится в диалоговом окне.

Вы можете попробовать пример в действии , а сам тестовый файл можно посмотреть .

Замечание: Строка http_request.overrideMimeType("text/xml"); вызовет ошибки в консоли JavaScript в Firefox 1.5 или более позднем, как описано в https://bugzilla.mozilla.org/show_bug.cgi?id=311724 , если страница вызванная с помощью XMLHttpRequest не является правильным XML (например, если это обычный текст). На самом деле это корректное поведение.

Замечание 2: Если вы посылаете запрос не на статический XML-файл, а на серверный скрипт, возвращающий XML, то нужно установить некоторые заголовки ответа, если вы планируете сделать вашу страницу работоспособной в Internet Explorer помимо Mozilla. Если вы не установите заголовок Content-Type: application/xml, IE будет сообщать об ошибке JavaScript, "Object Expected", после строки, где вы пытаетесь получить доступ к XML элементу. Если вы не установите заголовок Cache-Control: no-cache броузер будет кэшировать ответ и никогда не будет повторно отправлять запрос, что сделает отладку весьма «забавной».

Замечание 3: Если переменная http_request используется глобально, то конкурирующие функции, вызывающие makeRequest() могут конкурировать друг с другом, вызывая состязания. Объявление переменной http_request локально в функции и передача ее в alertContent() предотвращает состязания.

Замечание 4: При привязывании функции обратного вызова к onreadystatechange нельзя указывать аргументов. По этой причине не работает следующий код:

http_request.onreadystatechange = alertContents(http_request); // (не работает)

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

http_request.onreadystatechange = function() { alertContents(http_request); }; //1 (одновременный запрос)
http_request.onreadystatechange = alertContents; //2 (глобальная переменная)

Первый способ позволяет делать несколько запросов одновременно, а второй используется, когда переменная http_request является глобальной.

Замечание 5: В случае ошибки взаимодействия (например, если сервер упал), при попытке доступа к переменной.status метода onreadystatechange будет сгенерировано исключение. Убедитесь, что if...then заключено в try...catch. (См. https://bugzilla.mozilla.org/show_bug.cgi?id=238559).

function alertContents(http_request) {
try {
if (http_request.readyState == 4) {
if (http_request.status == 200) {
alert(http_request.responseText);
} else {
alert("С запросом возникла проблема.");
}
}
}
catch(e) {
alert("Произошло исключение: " + e.description);
}
}

Шаг 4 - Работа с XML ответом
В предыдущем примере, после того как был получен ответ на HTTP-запрос мы использовали responseText запрашиваемого объекта, который содержал данные файла test.html. Теперь давайте попробуем использовать свойство responseXML.

Прежде всего, давайте создадим правильный XML документ, который мы будем запрашивать. Документ (test.xml) содержит следующее:

< ?xml version="1.0" ?>

I"m a test.

В скрипте нам всего лишь необходимо заменить строку запроса на:

...
onclick="makeRequest("test.xml")">
...

var xmldoc = http_request.responseXML;
var root_node = xmldoc.getElementsByTagName("root").item(0);
alert(root_node.firstChild.data);

Чтобы узнать больше о методах DOM, посмотрите



Загрузка...