Принцип работы. AJAX - Что это

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 стал очень популярным методом для получения данных с сервера в фоновом режиме и динамического обновления страницы.

Разработка кода для JavaScript для реализации AJAX с нуля является весьма трудоемким и нудным процессом. Однако множество библиотек JavaScript, включая jQuery , имеют отличную высокоуровневую реализацию AJAX в виде набора методов и функций, которые облегчают и ускоряют построение веб сайтов.

В данной серии уроков мы рассмотрим основы построения запросов AJAX с помощью jQuery. Будут раскрыты следующие темы:

  • Что такое технология AJAX? Как она работает? В чем ее преимущества?
  • Как выполнить различные типы запросов AJAX с помощью jQuery?
  • Отправка данных на сервер с помощью запросов AJAX.
  • Обработка и выделение данных из ответов AJAX с сервера.
  • Как настроить обработку AJAX в jQuery и изменить установки по умолчанию?

Примечание: Уроки сконцентрированы на части JavaScript клиентской стороны. Но разработка серверной части также достаточно проста. Для более полной информации следует изучить материалы по языкам программирования серверной стороны, например PHP.

Что такое AJAX и чем он полезен?

AJAX является техникой разработки веб приложений, в которых JavaScript код, выполняющийся в браузере посетителя, связывается с веб сервером асинхронно , то есть в фоновом режиме. Отличие от обычных веб приложений заключаются в следующем:

  • Обычная веб страница содержит ссылки или формы, которые при нажатии или отправке создают запрос к новому адресу URL на веб сервере. Сервер отправляет полностью новую страницу HTML, которую затем выводит браузер, заменяя оригинальную страницу. Такой подход занимает много времени и плохо действует на посетителя, так как тому приходится ждать загрузки новой страницы.
  • При использовании технологии AJAX, JavaScript код делает запрос к URL на сервере. Код также может отправить данные вместе с запросом. Затем JavaScript код обрабатывает ответ сервера и действует соответствующим образом. Например, могут быть произведены вычисления с возвращаемыми данными, добавлен или обновлен виджет на странице, выдано сообщение посетителю об обновлении базы данных на сервере.

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

Фундаментальным моментом AJAX является объект JavaScript XMLHttpRequest . Он предоставляет ряд методов, таких как open() , send() и onreadystatechange() , которые могут быть использованы при отправке запросов AJAX на сервер и обработке ответов в фоновом режиме.

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

Для тех кто более любопытен, слово AJAX является аббревиатурой из первых букв выражения на английском языке "A synchronous J avaScript A nd X ML" (Асинхронный JavaScript и XML). Однако, термин может ввести в заблуждение - запрос не обязательно должен быть асинхронным и необязательно использовать XML для отправки данных.

Делаем запрос GET с помощью $.get()

Метод jQuery $.get() предоставляет легкий и удобный способ сделать простой запрос AJAX. Он выполняет запрос с помощью метода HTTP GET (используется для получения URL, например страниц и изображений), вместо метода POST (который традиционно используется для отправки данных формы).

В простейшей форме можно вызвать метод так:

Где url является адресом URL ресурса, от которого ожидается ответ. Обычно это скрипт на стороне сервера, который выполняет какие-нибудь действия и может возвращать некие данные:

$.get("http://example.com/getForecast.php");

Хотя можно также запросить статический документ:

$.get("http://example.com/mypage.html");

При запросе URL, вы можете отправить данные с запросом. Вы можете передать данные в строке запроса, так же как и при обычном запросе GET:

$.get("http://example.com/getForecast.php?city=rome&date=20120318");

Корректно будет сделать то же самое передав объект данных в качестве второго параметра методу $.get() . Объект данных должен содержать информацию в виде пар имя свойства/значение свойства. Например:

Var data = { city: "rome", date: "20120318" }; $.get("http://example.com/getForecast.php", data);

В качестве альтернативы вы можете передать данные методу $.get() как строку:

Var data = "city=rome&date=20120318"; $.get("http://example.com/getForecast.php", data);

Получаем данные с сервера

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

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

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

Function myCallback(returnedData) { // Делаем обработку данных returnedData }

Как только возвратная функция создана, вы можете передать ее в качестве третьего аргумента в метод $.get() :

Var data = { city: "rome", date: "20120318" }; $.get("http://example.com/getForecast.php", data, myCallback);

Определяем тип данных ответа

Обычно, серверная сторона передает данные в одном из нескольких типовых форматов, включая XML , JSON , JavaScript, или HTML. По умолчанию jQuery пытается определить наиболее подходящий формат и разобрать данные соответствующим образом. Но лучше явно определить формат.

Для указания формата надо передать четвертый аргумент методу $.get() . Данный аргумент может быть строкой из следующего списка:

  • "xml"
  • "json"
  • "script"
  • "html"

Например, если вы знаете, что скрипт сервера возвращает данные в формате JSON, то вызываете метод $.get() следующим образом:

$.get("http://example.com/getForecast.php", data, myCallback, "json");

Пример использования метода $.get()

Здесь приводится пример создания запроса AJAX с помощью метода $.get() и простая обработка ответа. Для работы примера нужно на сервере создать простой текстовый файл с именем getForecast.txt , содержащий следующий текст:

{ "city": "Васюки", "date": "18 марта 2012", "forecast": "Зубодробительный холод и слякоть", "maxTemp": +1 }

Данный файл будет имитировать ответ в формате JSON, который мог быть сформирован скриптом прогноза погоды на сервере.

Затем создаем страницу showForecast.html в той же папке что и getForecast.txt:

Прогноз погоды $(function() { $("#getForecast").click(function() { var data = { city: "Васюки", date: "20120318" }; $.get("getForecast.txt", data, success, "json"); }); function success(forecastData) { var forecast = forecastData.city + " прогноз на " + forecastData.date; forecast += ": " + forecastData.forecast + ". Максимальная температура: " + forecastData.maxTemp + "C"; alert(forecast); } }); Получить прогноз погоды

Открываем showForecast.html в браузере и нажимаем кнопку "Получить прогноз погоды". В окне сообщения получим прогноз погоды с нашего сервера.

Вот как работает данный код:

  • showForecast.html содержит элемент button "Получить прогноз погоды" с ID getForecast .
  • JavaScript вверху страницы выполняется как только страница будет загружена и DOM окажется в состоянии готовности.
  • Код JavaScript сначала привязывает обработчик события click к кнопке #getForecast . Данный обработчик выполняет AJAX запрос GET к getForecast.txt , передавая название города и дату для прогноза. Также определяется возвратная функция success(), которая будет выполняться по завершению запроса. Формат возвращаемых сервером данных определяется как JSON.
  • Файл getForecast.txt возвращает браузеру данные прогноза в формате JSON.
  • Вызывается функция success() . jQuery разбирает данные JSON, полученные от getForecast.txt , конвертирует их в объект JavaScript, и передает их в функцию.
  • Функция возвращает объект данных forecastData и выводит сообщение, которое содержит несколько свойств объекта, включая название города, прогноз и температуру.
  • Простой пример в несколько строк демонстрирует работу запроса AJAX с использованием метода $.get() .

    Сейчас в сети Интернет наблюдается очень активное развитие (и даже использование) новых технологий. Одна из таких технологий — AJAX.

    Что такое AJAX?

    AJAX — это аббревиатура, которая означает Asynchronous Javascript and XML. На самом деле, AJAX не является новой технологией, так как и Javascript, и XML существуют уже довольно продолжительное время, а AJAX — это синтез обозначенных технологий. AJAX чаще всего ассоцириуется с термином Web 2.0 и преподносится как новейшее Web-приложение.

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

    Обобщим достоинства AJAX:

    • Возможность создания удобного Web-интерфейса
    • Активное взаимодействие с пользователем
    • Удобство использования

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

    Обмен данными

    Для того, чтобы осуществлять обмен данными, на странице должен быть создан объект XMLHttpRequest, который является своеобразным посредником между Браузером пользователя и сервером (рис. 1). С помощью XMLHttpRequest можно отправить запрос на сервер, а также получить ответ в виде различного рода данных.

    Обмениваться данными с сервером можно двумя способами. Первый способ — это GET-запрос. В этом запросе вы обращаетесь к документу на сервере, передавая ему аргументы через сам URL. При этом на стороне клиента будет логично использовать функция Javascript`а escape для того, чтобы некоторые данные не прервали запрос.

    Клиент часть, написанная на Javascript, должна обеспечивать необходимую функциональность для безопасного обмена с сервером и предоставлять методы для обмена данными любым из вышеперечисленных способов. Серверная часть должна обрабатывать входные данные, и на основе их генерировать новую информацию (например, работая с базой данных), и отдавать ее обратно клиенту. Например, для запроса информации с сервера можно использовать обычный GET-запрос с передачей нескольких и небольших по размеру параметров, а для обновления информации, или добавления новой информации потребуется использовать уже POST-запрос, так как он позволяет передавать большие объемы данных.

    Как уже было сказано, AJAX использует асинхронную передачу данных. Это значит, что пока идёт передача данных, пользователь может совершать другие, необходимые ему действия. В это время следует оповестить пользователя о том, что идёт какой-либо обмен данными, иначе пользователь подумает, что произошло что-то не то и может покинуть сайт, или повторно вызвать «зависшую», по его мнению, функцию. Индикация во время обмена данными в приложении Web 2.0 играет очень важную роль: посетители могли еще не привыкнуть к таким способам обновления страницы.

    Ответ от сервера может быть не только XML, как следует из названия технологии. Помимо XML, можно получить ответ в виде обычного текста, или же JSON (Javascript Object Notation). Если ответ был получен простым текстом, то его можно сразу вывести в контейнер на странице. При получении ответа в виде XML, обычно происходит обработка полученного XML документа на стороне клиента и преобразование данных к (X)HTML. При получении ответа в формате JSON клиент должен лишь выполнить полученный код (функция Javascript`а eval) для получения полноценного объекта Javascript. Но здесь нужно быть осторожным и учитывать тот факт, что с использованием этой технологии может быть передан вредоносный код, поэтому перед выполнением полученного с сервера кода следует его тщательно проверить и обработать. Существует такая практика, как «холостой» запрос, при котором никакой ответ от сервера не приходит, лишь изменяются данные на стороне сервера.

    В разных браузерах данный объект обладает разными свойствами, но в целом он совпадает.

    Методы объекта XMLHttpRequest

    Заметьте, что названия методов записаны в том же стиле (Camel-style), что и другие функции Javascript. Будьте внимательны при их использовании.

    abort() — отмена текущего запроса к серверу.

    getAllResponseHeaders() — получить все заголовки ответа от сервера.

    getResponseHeader(«имя_заголовка») — получить указаный заголовок.

    open(«тип_запроса»,»URL»,»асинхронный»,» имя_пользователя»,» пароль») — инициализация запроса к серверу, указание метода запроса. Тип запроса и URL — обязательные параметры. Третий аргумент — булево значение. Обычно всегда указывается true или не указывается вообще (по умолчанию — true). Четвертый и пятый аргументы используются для аутентификации (это очень небезопасно, хранить данные об аутентификации в скрипте, так как скрипт может посмотреть любой пользователь).

    send(«содержимое») — послать HTTP запрос на сервер и получить ответ.

    setRequestHeader(«имя_заголовка»,»значение») — установить значения заголовка запроса.

    Свойства объекта XMLHttpRequest

    onreadystatechange — одно из самых главных свойств объекта XMLHttpRequest. С помощью этого свойства задаётся обработчик, который вызывается всякий раз при смене статуса объекта.

    readyState — число, обозначающее статус объекта.

    responseText — представление ответа сервера в виде обычного текста (строки).

    responseXML — объект документа, совместимый с DOM, полученного от сервера.

    status — состояние ответа от сервера.

    statusText — текстовое представление состояния ответа от сервера.

    Следует подробнее расммотреть свойство readyState:

    • 0 — Объект не инициализирован.
    • 1 — Объект загружает данные.
    • 2 — Объект загрузил свои данные.
    • 3 — Объек не полностью загружен, но может взаимодействовать с пользователем.
    • 4 — Объект полностью инициализирован; получен ответ от сервера.

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

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

    Как уже говорилось выше, создание данного объекта для каждого типа браузера — уникальный процесс.

    Например, для создания объекта в Gecko-совместимых браузерах, Konqueror`е и Safari, нужно использовать следующее выражение:

    var Request = new XMLHttpRequest();

    А для Internet Explorer`а используется следующее:

    var Request = new ActiveXObject("Microsoft.XMLHTTP");

    var Request = new ActiveXObject("Msxml2.XMLHTTP");

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

    function CreateRequest() { var Request = false; if (window.XMLHttpRequest) { //Gecko-совместимые браузеры, Safari, Konqueror Request = new XMLHttpRequest(); } else if (window.ActiveXObject) { //Internet explorer try { Request = new ActiveXObject("Microsoft.XMLHTTP"); } catch (CatchException) { Request = new ActiveXObject("Msxml2.XMLHTTP"); } } if (!Request) { alert("Невозможно создать XMLHttpRequest"); } return Request; }

    После всего этого можно создавать данный объект и не беспокоится за работоспособность на популярных браузерах. Но создать объект можно в разных местах. Если создать его глобально, то в определенный момент времени возможен будет только один запрос к серверу. Можно создавать объект всякий раз, как происходит запрос к серверу (это почти полностью решит проблему).

    Запрос к серверу

    Алгоритм запроса к серверу выглядит так:

    • Проверка существования XMLHttpRequest.
    • Инициализация соединения с сервером.
    • Посылка запрса серверу.
    • Обработка полученных данных.

    Для создания запроса к серверу мы создадим небольшую функцию, которая будет по функциональности объединять в себе функции для GET и POST запросов.

    /* Функция посылки запроса к файлу на сервере r_method - тип запроса: GET или POST r_path - путь к файлу r_args - аргументы вида a=1&b=2&c=3... r_handler - функция-обработчик ответа от сервера */ function SendRequest(r_method, r_path, r_args, r_handler) { //Создаём запрос var Request = CreateRequest(); //Проверяем существование запроса еще раз if (!Request) { return; } //Назначаем пользовательский обработчик Request.onreadystatechange = function() { //Если обмен данными завершен if (Request.readyState == 4) { //Передаем управление обработчику пользователя r_handler(Request); } } //Проверяем, если требуется сделать GET-запрос if (r_method.toLowerCase() == "get" && r_args.length > 0) r_path += "?" + r_args; //Инициализируем соединение Request.open(r_method, r_path, true); if (r_method.toLowerCase() == "post") { //Если это POST-запрос //Устанавливаем заголовок Request.setRequestHeader("Content-Type","application/x-www-form-urlencoded; charset=utf-8"); //Посылаем запрос Request.send(r_args); } else { //Если это GET-запрос //Посылаем нуль-запрос Request.send(null); } }

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

    function ReadFile(filename, container) { //Создаем функцию обработчик var Handler = function(Request) { document.getElementById(container).innerHTML = Request.responseText; } //Отправляем запрос SendRequest("GET",filename,"",Handler); }

    Именно таким образом происходит взаимодействие с сервером.

    Обработка ответа

    В предыдущем примере мы сделали функцию запроса к серверу. Но она, по сути, небезопасна, так как мы не обрабатываем состояния объекта и состояния ответа от сервера.

    Дополним наш код, чтобы он смог выводить визуальное оповещение о процессе загрузки.

    Request.onreadystatechange = function() { //Если обмен данными завершен if (Request.readyState == 4) { //Передаем управление обработчику пользователя r_handler(Request); } else { //Оповещаем пользователя о загрузке } } ...

    Как вы уже знаете, объект XMLHttpRequest позволяет узнать статус ответа от сервера. Воспользуемся этой возможностью.

    Request.onreadystatechange = function() { //Если обмен данными завершен if (Request.readyState == 4) { if (Request.status == 200) { //Передаем управление обработчику пользователя r_handler(Request); } else { //Оповещаем пользователя о произошедшей ошибке } } else { //Оповещаем пользователя о загрузке } } ...

    Варианты ответа от сервера

    От сервера можно получить данные нескольких видов:

  • Обычный текст
  • Если вы получаете обычный текст, то вы можете сразу же направить его в контейнер, то есть на вывод. При получении данных в виде XML вы должны обработать данные с помощью DOM-функций, и представить результат с помощью HTML.

    JSON — это объектная нотация Javascript. С ее помощью можно представить объект в виде строки (здесь можно привести аналогию с функцией сериализации). При получении JSON-данных вы должны выполнить их, чтобы получить полноценный объект Javascript и произвести с ним необходимые операции. Помните, что такая передача данных и выполнение их не являются безопасными. Вы должны следить за тем, что поступает на исполнение.

    Все начинающие 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 и с чем его едят.

    Что такое AJAX ? Пример реализации.

    AJAX, или, более длинно, A synchronous J avascript A nd X ml - технология для взаимодействия с сервером без перезагрузки страниц.

    За счет этого уменьшается время отклика и веб-приложение по интерактивности больше напоминает десктоп.

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

    Вот код кнопки в примере выше:

    При нажатии она вызывает функцию vote , которая отправляет запрос на сервер, ждет ответа, а затем показывает сообщение об этом в div "е под кнопкой:

    Здесь будет ответ сервера

    Для обмена данными с сервером используется специальный объект XmlHttpRequest , который умеет отправлять запрос и получать ответ с сервера. Кроссбраузерно создать такой объект можно, например, так:

    Function getXmlHttp(){ var xmlhttp; try { xmlhttp = new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) { try { xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); } catch (E) { xmlhttp = false; } } if (!xmlhttp && typeof XMLHttpRequest!="undefined") { xmlhttp = new XMLHttpRequest(); } return xmlhttp; }

    Более подробно о деталях реализации AJAX с использованием XmlHttpRequest и других транспортов можно почитать в разделе про общение с сервером .

    Здесь мы не будем на этом останавливаться и перейдем сразу к функции vote:

    // javascript-код голосования из примера function vote() { // (1) создать объект для запроса к серверу var req = getXmlHttp() // (2) // span рядом с кнопкой // в нем будем отображать ход выполнения var statusElem = document.getElementById("vote_status") req.onreadystatechange = function() { // onreadystatechange активируется при получении ответа сервера if (req.readyState == 4) { // если запрос закончил выполняться statusElem.innerHTML = req.statusText // показать статус (Not Found, ОК..) if(req.status == 200) { // если статус 200 (ОК) - выдать ответ пользователю alert("Ответ сервера: "+req.responseText); } // тут можно добавить else с обработкой ошибок запроса } } // (3) задать адрес подключения req.open("GET", "/ajax_intro/vote.php", true); // объект запроса подготовлен: указан адрес и создана функция onreadystatechange // для обработки ответа сервера // (4) req.send(null); // отослать запрос // (5) statusElem.innerHTML = "Ожидаю ответа сервера..." }

    Поток выполнения, использованный vote, довольно типичен и выглядит так:

  • Функция создает объект XmlHttpRequest
  • назначает обработчик ответа сервера onreadystatechange
  • открывает соединение open
  • отправляет запрос вызовом send (ответ сервера принимается срабатывающей в асинхронном режиме функцией onreadystatechange)
  • показывает посетителю индикатор состояния процесса
  • Серверный обработчик, к которому обращен AJAX-запрос (в примере это vote.php) по сути ничем не отличается от обычной страницы. AJAX-запрос, отправляемый XmlHttpRequest , ничем не отличается от обычного запроса.

    Просто текст, который возвращает сервер, не показывается как HTML, а читается и обрабатывается функцией onreadystatechange .

    Смысл AJAX - в интеграции технологий

    Технология AJAX использует комбинацию:

    • (X)HTML, CSS для подачи и стилизации информации
    • DOM-модель, операции над которой производятся javascript на стороне клиента, чтобы обеспечить динамическое отображение и взаимодействие с информацией
    • XMLHttpRequest для асинхронного обмена данными с веб-сервером. В некоторых AJAX-фреймворках и в некоторых ситуациях, вместо XMLHttpRequest используется IFrame, SCRIPT-тег или другой аналогичный транспорт.
    • JSON часто используется для обмена данными, однако любой формат подойдет, включая форматированный HTML, текст, XML и даже какой-нибудь EBML

    Типичное AJAX-приложение состоит как минимум из двух частей.

    Первая выполняется в браузере и написана, как правило, на JavaScript, а вторая - находится на сервере и написана, например, на Ruby, Java или PHP .

    Между этими двумя частями происходит обмен данными через XMLHttpRequest(или другой транспорт).

    Что я могу сделать с помощью AJAX ?

    Смысл AJAX - в интерактивности и быстром времени отклика.

    Небольшие элементы управления

    В первую очередь AJAX полезен для небольших элементов, связанных с элементарными действиями: добавить в корзину, подписаться, и т.п.

    Динамическая подгрузка данных с сервера.

    Например, дерево, узлы которого подгружаются по мере раскрытия.

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

    • Проверка ошибок ввода формы ДО сабмита

      На сервер передается имя пользователя, результат проверки возвращается на страницу.

    • "Мгновенная" загрузка

      Браузер обращается к серверу только за данными, а не обновляет весь громоздкий интерфейс

    • Автоматическая "доставка" писем в открытую папку

      Время от времени отправляется запрос на сервер и, если пришли новые письма, они появляются в браузере.

    • Автодополнение

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

    Результат: обширная популярность, высокий спрос на account"ы с момента открытия.

    Синхронная модель VS Асинхронная модель

    В обычном программировании все операции носят синхронный характер, т.е выполняются одна за другой.

    Условно говоря, мы действуем так:

  • закидываем удочку
  • ждем, когда клюнет
  • клюнуло - включаем подтяжку спиннинга
  • При асинхронном подходе мы:

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

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

    Асинхронное программирование сложнее, чем синхронное, и поначалу непривычно, т.к в нем заранее задается то, что сработает после .
    Т.е, программу "что делать, когда клюнет" нужно задать до того, как клюнуло, и вообще неизвестно, есть ли в водоеме рыба.

    Существуют приемы, облегчающие асинхронное программирование, например, отложенный объект Deferred (Twisted,Dojo,Mochikit), но об этом - в отдельной статье.

    Синхронная и асинхронная модель в AJAX

    Вернемся к нашим баранам: браузеру, серверу и, скажем, базе данных.

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

    Все процессы выполняются последовательно, один за другим.

    Сетевые задержки включены во время ожидания, обозначенное на схеме серым цветом.

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

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

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

    Пользователь может написать комментарии, заполнить и отослать форму и т.п: Могут производиться новые асинхронные запросы.

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

    Из-за такого разрыва между действием и реальным результатом приложение становится гораздо более чувствительно к ошибкам.

    Особенно в случае нескольких одновременных асинхронных запросов, нужно заботиться об очередности выполнения и ответа (race-conditions) и, в случае ошибки, оставлять приложение в целостном (consistent) состоянии.

    Особенности асинхронной модели
    • Сложность в реализации
      • Недостаточные возможности браузера (javascript)
      • Асинхронная модель сложнее для отладки
    • Race conditions
      • Неопределена последовательность выполнения
      • Можно делать много одновременных задач ("удочек"), но задача, начатая первой, может окончиться последней.
    • Реакция тут же, но неизвестно, какой будет результат. Усложнена обработка ошибок
      • Ошибок коммуникации - разрыв связи, и т.п.
      • Пользовательских ошибок - например, не хватило привилегий
    • Контроль целостности (bugproof)
      • Например, редактор отправил асинхронный запрос на удаление ветки дерева. Добавление в нее нужно отключить, пока не придет ответ сервера. Если вдруг не хватило привилегий, то операция не удалась.
    • Интерактивность
    • Быстрый интерфейс

    Плюсов всего два, зато какие! Овчинка стоит выделки.

    Асинхронный drag"n"drop.

    Иногда для асинхронных операций необходимо делать различные "финты ушами". Например, хочется сделать drag"n"drop в дереве, т.е перетаскивать статьи из одного раздела в другой мышкой, и чтобы они на сервере в базе данных меняли родителя.

    Drag"n"drop - это "взял мышей объект - положил куда надо - готово". Но в асинхронной модели не может быть все прям сразу "готово".
    Надо проверить привилегии на сервере, проверить, существует ли еще объект, вдруг его удалил другой пользователь.

    Надо как-то показать, что процесс пошел, но результат "ща будет..". А как? В асинхронной модели указатель мыши не может просто так зависнуть над объектом, превратившись в часики.

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

    Stale context, устаревший контекст

    В примере с drag"n"drop также затронута проблема "stale context" - устаревшего контекста.

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

    Как правило, для преодоления таких казусов используются следующие средства:

    Политика редактирования

    Это когда все знают кто чего делает и на уровне деления полномочий и личного общения такие удаления согласовывают. Вариант заведомо небезопасный, но обычно работающий.

    Локинг и/или версионный контроль

    Локинг - блокирование редактируемых документов.

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

    Более подробно о локинге и версионности можно почитать, например, в документации к системе версионного контроля Subversion .

    Автообновление контекста

    Проблема устаревшего контента может быть на 99% решена при помощи мгновенного автообновления.

    Браузер держит постоянное соединение с сервером (или делает время от времени корректирующие запросы) - и нужные изменения отсылаются по этому каналу.

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

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