Как настроить смартфоны и ПК. Информационный портал

AJAX: что это такое, влияние на seo, преимущества и недостатки технологии. Использование 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 и произвести с ним необходимые операции. Помните, что такая передача данных и выполнение их не являются безопасными. Вы должны следить за тем, что поступает на исполнение.

Пример кода JSON:
{ "data": { "misc": [ { "name" : "JSON-элемент один", "type" : "Подзаголовок 1" }, { "name" : "JSON-элемент два", "type" : "Подзаголовок 2" } ] } }

При получении такого кода, производим следующее действие:

Var responsedata = eval("(" + Request.responseText + ")")

После выполнения данного кода вам будет доступен объект responsedata .

Работа с серверными языками программирования

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

По традиции, начнем с приветствия нашему замечательному миру:

Echo "Hello, World!";

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

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

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, для быстрого и эффективного взаимодействия с посетителем. 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() .

    Пять лет назад вы были гадким утенком (с которым никто не разговаривал), если не знали XML. Восемнадцать месяцев назад в центре внимания оказался Ruby, а программисты, не знающие что с ним происходит, не были приглашены к бачку с охлажденной водой. Сегодня, если вы хотите попасть на технологическую вечеринку, нужен Ajax.

    Однако, Ajax – это далеко не чья-то прихоть, а мощный подход к созданию Web-сайтов, который не так трудно изучить, как полностью новый язык.

    Перед тем, как я погружусь в детали Ajax, давайте потратим пару минут на осмысление того, что же делает Ajax. Когда в наше время вы пишете приложение, у вас есть два основных варианта:

    • Настольные приложения
    • Web-приложения

    Оба варианта знакомы; настольные приложения обычно поставляются на CD (или иногда загружаются с Web-сайта) и устанавливаются целиком на вашем компьютере. Они могут использовать Интернет для загрузки обновлений, но код, выполняющий эти приложения, размещен на вашем рабочем столе. Web-приложения (и это не удивительно) работают где-то на Web-сервере, а вы обращаетесь к этим приложениям через ваш Web-браузер.

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

    С другой стороны, Web-приложения обычно самые свежие по времени и предоставляют возможности, которые вы никогда бы не смогли иметь на вашем компьютере (вспомните Amazon.com и eBay). Однако с могуществом Web приходит ожидание – ожидание ответа от сервера, ожидание обновления экрана, ожидание ответа на запрос и генерирования новой страницы.

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

    Так чего же мы ждем? Начнем рассмотрение Ajax и способов превращения ваших неуклюжих Web-интерфейсов в чувствительные Ajax-приложения.

    Старая технология, новые хитрости

    Что касается Ajax, то реальность такова, что он охватывает много технологий – для его освоения необходимо углубиться в несколько различных технологий (вот почему я разобью на независимые части первые несколько статей из этой серии). Хорошей новостью является то, что вы, возможно, уже знаете достаточно о многих из этих технологий – большинство из этих индивидуальных технологий изучаются легко (определенно не так трудно, как язык программирования полностью, например Java или Ruby).

    Определение Ajax

    Между прочим, Ajax – это аббревиатура от Asynchronous JavaScript and XML (и DHTML, и т.д.). Фраза была придумана Джессе Джеймсом Гарретом из Adaptive Path (см. раздел ) и, по словам Джессе, не предназначалась быть аббревиатурой.

    Вот основные технологии, вовлеченные в Ajax-приложения:

    • HTML используется для создания Web-форм и указания полей для использования в вашем приложении.
    • JavaScript-код – это основной код, выполняющий Ajax-приложения и обеспечивающий взаимодействие с серверными приложениями.
    • DHTML, или Dynamic HTML, помогает динамически обновлять формы. Вы будете использовать div , span и другие динамические HTML-элементы для разметки вашего HTML.
    • DOM, Document Object Model (объектная модель документов), будет использоваться (через код JavaScript) для работы и со структурой вашего HTML, и (в некоторых случаях) с XML, полученным от сервера.

    Рассмотрим все это по отдельности и разберемся в том, что делает каждая из этих технологий. Я исследую каждую из них в следующих статьях; сейчас просто познакомимся поближе с этими компонентами и технологиями. Чем больше вы знаете о них, тем легче перейти от бессистемных знаний к освоению каждой из них (и действительно улучшить процесс разработки Web-приложений).

    Объект XMLHttpRequest

    Первый объект, о котором вы хотите узнать, возможно, самый новый для вас; он называется XMLHttpRequest . Это объект JavaScript, и он создается так же просто, как показано в .

    Листинг 1. Создание нового объекта XMLHttpRequest

    var xmlHttp = new XMLHttpRequest();

    Я детально расскажу об этом объекте в следующей статье, а сейчас осознайте, что это объект, который управляет всем вашим взаимодействием с сервером. Прежде чем идти дальше, остановитесь и подумайте об этом – это технология JavaScript в объекте XMLHttpRequest , который общается с сервером. Это не обычный ход работы приложения, и именно здесь заключается почти вся магия Ajax.

    В нормальных Web-приложениях пользователи заполняют поля форм и нажимают кнопку Submit (подтвердить). Затем форма передается на сервер полностью, сервер обрабатывает сценарий (обычно PHP или Java, возможно, CGI-процесс или что-то в этом роде), а потом передает назад всю новую страницу. Эта страница может быть HTML-страницей с новой формой с некоторыми заполненными данными, либо страницей подтверждения, либо, возможно, страницей с какими-то выбранными вариантами, зависящими от введенных в оригинальную форму данных. Естественно, пока сценарий или программа на сервере не обработается и не возвратится новая форма, пользователи должны ждать. Их экраны очистятся и будут перерисовываться по мере поступления новых данных от сервера. Вот где проявляется низкая интерактивность – пользователи не получают немедленной обратной реакции и определенно чувствуют себя не так, как при работе с настольными приложениями.

    Ajax по существу помещает технологию JavaScript и объект XMLHttpRequest между вашей Web-формой и сервером. Когда пользователи заполняют формы, данные передаются в какой-то JavaScript-код, а не прямо на сервер. Вместо этого JavaScript-код собирает данные формы и передает запрос на сервер. Пока это происходит, форма на экране пользователя не мелькает, не мигает, не исчезает и не блокируется. Другими словами, код JavaScript передает запрос в фоновом режиме; пользователь даже не замечает, что происходит запрос на сервер. Более того, запрос передается асинхронно, а это означает, что ваш JavaScript-код (и пользователь) не ожидают ответа сервера. То есть, пользователи могут продолжать вводить данные, прокручивать страницу и работать с приложением.

    Затем сервер передает данные обратно в ваш JavaScript-код (все еще находящийся в вашей Web-форме), который решает, что делать с данными. Он может обновить поля формы "на лету", придавая свойство немедленности вашему приложению – пользователи получают новые данные без подтверждения или обновления их форм. JavaScript-код может даже получить данные, выполнить какие-либо вычисления и передать еще один запрос, и все это без вмешательства пользователя! В этом заключается мощь XMLHttpRequest . Он может общаться с сервером по своему желанию, а пользователь даже не догадывается о том, что происходит на самом деле. В результате мы получаем динамичность, чувствительность, высокую интерактивность настольного приложения вместе со всеми возможностями интернет.

    Добавление JavaScript-кода

    После того, как вы разберетесь с XMLHttpRequest , оставшийся JavaScript-код превращается в рутинную работу. Фактически, вы будете использовать JavaScript-код для небольшого числа основных задач:

    Для выполнения первых двух задач вы должны очень хорошо знать метод getElementById() , приведенный в .

    Листинг 2. Сбор и установка значений полей при помощи JavaScript-кода

    // Получить значение поля "phone" и записать его в переменную phone var phone = document.getElementById("phone").value; // Установить значения в форме, используя массив response document.getElementById("order").value = response; document.getElementById("address").value = response;

    Здесь нет ничего такого уж выдающегося, и это здорово! Вы должны начать понимать, что нет ничего чрезмерно сложного во всем этом. Как только вы освоите XMLHttpRequest , оставшаяся часть вашего Ajax-приложения будет простым JavaScript-кодом, похожим на приведенный в , смешанным с немного более умным HTML. К тому же, время от времени есть немного работы с DOM... Итак, давайте рассмотрим это.

    Завершение с DOM

    И последнее, хотя и не менее важное, - это DOM, Document Object Model (объектная модель документа). Для некоторых из вас слухи о DOM могут быть немного пугающими – она не часто используется HTML-дизайнерами и даже немного не свойственна кодировщикам на JavaScript (пока вы действительно не решаете каких-либо программных задач высокого уровня). Вы можете найти широкое применение DOM в тяжеловесных программах, написанных на языках Java и C/C++; фактически, это и принесло DOM репутацию сложной и трудной для изучения.

    К счастью, использование DOM в технологии JavaScript является делом легким и в основном интуитивным. Сейчас мне, наверное, надо было бы рассказать вам, как использовать DOM или хотя бы привести пару примеров кода, но даже это сбило бы вас с верного пути. Дело в том, что вы можете продвинуться довольно далеко в изучении Ajax без необходимости примешивать сюда DOM, и это именно тот путь, который я хочу вам показать. Я вернусь к DOM в следующей статье, но сейчас просто знайте, что она где-то здесь. Когда вы начнете передавать XML-данные вперед и назад между вашим JavaScript-кодом и реальными изменениями HTML-формы, вы углубитесь в DOM. А пока можно эффективно работать с Ajax без DOM, так что пока отложим ее до поры до времени.

    Получение объекта Request

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

    Помните те ужасные войны браузеров, происходившие несколько лет назад, и как ничто не работало одинаково в разных браузерах? Поверите вы или нет, но те войны продолжаются до сих пор, хотя и с намного меньшим масштабом. И, сюрприз: XMLHttpRequest – это одна из жертв этих войн. Поэтому вы должны выполнить несколько различных действий для обеспечения возможности работы XMLHttpRequest . Я покажу вам как это сделать шаг за шагом.

    Работа с браузерами Microsoft

    Браузер Microsoft Internet Explorer для обработки XML использует анализатор MSXML (ссылки на дополнительную информацию по MSXML вы можете найти в разделе ). Поэтому, когда вы пишете Ajax-приложения, которые должны работать в Internet Explorer, необходимо создать объект особым способом.

    Однако, это не так то и легко. На самом деле в ходу две различных версии MSXML. Версия MSXML зависит от версии технологии JavaScript, установленной в Internet Explorer, поэтому вам нужно написать код, подходящий для обеих версий. Взгляните на , в котором приведен код для создания XMLHttpRequest в браузерах Microsoft.

    Листинг 3. Создание объекта XMLHttpRequest в браузерах Microsoft

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

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

    xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");

    xmlHttp = new ActiveXObject("Microsoft.XMLHTTP"); .

    В двух словах, этот код пытается создать объект, используя одну версию MSXML; если это не получится, создается объект для второй версии. Изящно, да? Если ничего не сработало, переменная xmlHttp устанавливается в false, для того чтобы указать вашему коду, что что-то не так. В этом случае вы, возможно, работаете с браузером не от Microsoft и должны использовать другой код для выполнения работы.

    Работа с Mozilla и браузерами не от Microsoft

    Если Internet Explorer не ваш браузер, либо вы пишете код для браузеров не от Microsoft, вам нужен другой код. Фактически, это простая строка, которую вы видели в :

    var xmlHttp = new XMLHttpRequest object; .

    Эта намного более простая строка создает объект XMLHttpRequest в Mozilla, Firefox, Safari, Opera и в большой степени в каждом браузере не от Microsoft, поддерживающем Ajax в любой форме или разновидности.

    Объединение

    Мы хотим поддерживать все браузеры. Кто хочет писать приложение, работающее только в Internet Explorer, или приложение, работающее только во всех остальных браузерах? Еще хуже, хотите ли вы написать ваше приложение дважды? Конечно, нет! Итак, объединим поддержку для Internet Explorer и для остальных браузеров. В приведен код, делающий это.

    Листинг 4. Создание объекта XMLHttpRequest для всех браузеров

    /* Создание нового объекта XMLHttpRequest для общения с Web-сервером */ var xmlHttp = false; /*@cc_on @*/ /*@if (@_jscript_version >= 5) try { xmlHttp = new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) { try { xmlHttp = new ActiveXObject("Microsoft.XMLHTTP"); } catch (e2) { xmlHttp = false; } } @end @*/ if (!xmlHttp && typeof XMLHttpRequest != "undefined") { xmlHttp = new XMLHttpRequest(); }

    Пока проигнорируйте комментарии и непонятные теги, типа @cc_on ; это специальные команды JavaScript-компилятора, которые мы рассмотрим детально в моей следующей статье, которая будет полностью посвящена XMLHttpRequest . Основу этого кода можно разделить на три шага:

  • Создайте переменную xmlHttp для ссылки на объект XMLHttpRequest , который вы создадите.
  • В блоке try создайте объект в браузерах Microsoft:
    • В блоке try создайте объект с использованием объекта Msxml2.XMLHTTP .
    • Если это не получится, В блоке try создайте объект с использованием объекта Microsoft.XMLHTTP .
  • Если xmlHttp все еще не установлен, создайте объект для остальных браузеров.
  • В конце этого процесса xmlHttp должен ссылаться на корректный объект XMLHttpRequest , независимо от используемого пользователем браузера.

    Пара слов о защите

    Как насчет защиты? Современные браузеры предлагают пользователям возможность повысить уровень безопасности, отключить технологию JavaScript и запретить множество настроек в своих браузерах. В этих ситуациях ваш код, вероятно, не будет работать ни при каких обстоятельствах. Для таких ситуаций вы должны элегантно решить проблемы – есть, по крайней мере, одна статья об этом, а одну я напишу позднее (это, наверное, будет длинная серия, но не беспокойтесь – вы все освоите до окончания этой серии статей). Пока же вы пишете устойчивый, но не совершенный код, который отлично подходит для изучения Ajax. Вы вернетесь к более качественному коду позже.

    Запрос/ответ в мире Ajax

    Итак, вы уже знакомы с Ajax и имеете базовое представление об объекте XMLHttpRequest и о том, как создать его. Если вы читали внимательно, то вы даже понимаете, что это технология JavaScript общается с любым Web-приложением на сервере, а не ваша HTML-форма, которую вы подтвердили напрямую.

    Что мы пропустили? Как на самом деле использовать XMLHttpRequest . Поскольку это критический код, который вы будете использовать в некоторых формах в каждом вашем Ajax-приложении, рассмотрим коротко, как выглядит базовая модель запрос/ответ в Ajax.

    Выполнение запроса

    У вас есть ваш превосходный новый объект XMLHttpRequest ; приведем его в движение. Во-первых, нам понадобится JavaScript-метод, который ваша Web-страница может вызвать (например, когда пользователь вводит текст или выбирает вариант из меню). Затем, нужно следовать одной и той же основной схеме практически во всех ваших Ajax-приложениях:

  • Получить какие-либо данные из Web-формы.
  • Создать URL для подключения.
  • Открыть соединение с сервером.
  • Установить функцию для сервера, которая выполнится после его ответа.
  • Передать запрос.
  • Листинг 6. Обработка ответа от сервера

    function updatePage() { if (xmlHttp.readyState == 4) { var response = xmlHttp.responseText; document.getElementById("zipCode").value = response; } }

    Опять же, код не является трудным или сложным. Он ожидает, пока сервер не вызовет его с нужным состоянием готовности, и затем использует значение, которое сервер возвращает (в данном случае ZIP-код для введенного пользователем города и штата), для установки другого поля формы. В результате поле zipCode неожиданно появляется с ZIP-кодом, но пользователь ни разу не щелкнул по кнопке ! Это поведение настольного приложения, о чем я говорил ранее. Оперативность, ощущение динамичности и т.д., а все с маленьким Ajax-кодом.

    Наблюдательные читатели, возможно, заметят, что поле zipCode является обычным текстовым полем. После возврата сервером ZIP-кода и установки этого поля методом updatePage() в значение ZIP-кода города/штата пользователи могут переопределить это значение. Так сделано умышленно по двум причинам: сохранить этот пример простым и показать вам, что иногда нужно, чтобы пользователи имели возможность переопределить значения, возвращенные сервером. Помните об обоих моментах; они важны при хорошем дизайне пользовательского интерфейса.

    Перехват в Web-формах

    Что нам осталось? В сущности, не много. Вы имеете JavaScript-метод, собирающий введенную пользователем в форму информацию, передаете ее серверу, предоставляете еще один JavaScript-метод для обработки ответа и даже устанавливаете значение поля, когда этот ответ приходит. Все что осталось на самом деле – вызвать этот первый метод и запустить полный процесс. Вы могли бы, очевидно, добавить кнопку в вашу HTML-форму, но это же старый, добрый 2001 год, не так ли? Воспользуемся возможностями технологии JavaScript, как показано в .

    Листинг 7. Запуск Ajax-процесса

    City:

    State:

    Zip Code:

    Если это выглядит как еще один кусок в рутинном, в некоторой степени, коде – вы правы, так и есть! Когда пользователь вводит новое значение для любого из полей city или state, запускается метод callServer() , и Ajax-функция начинается. Вам кажется, что вы начинаете понимать суть вещей? Отлично!

    В заключение

    В настоящий момент вы, возможно, не готовы взять и написать ваше первое Ajax-приложение, по крайней мере, пока не исследовали раздел . Однако, вы уже можете начать понимать основную идею о том, как работают такие приложения и что такое объект XMLHttpRequest . В готовящихся статьях вы изучите этот объект, а также то, как контролировать взаимодействие JavaScript-to-server и работать с HTML-формами, и даже разберетесь с DOM.

    Пока же потратьте некоторое время на размышления о том, насколько мощными могут быть Ajax-приложения. Представьте себе Web-форму, которая реагирует не только тогда, когда вы нажимаете кнопку, но и когда вы вводите данные в поле, когда выбираете вариант из списка вариантов и даже когда перемещаете курсор по экрану. Подумайте о том, что на самом деле означает слово асинхронный . Подумайте о JavaScript-коде, выполняющемся и не ожидающем , пока сервер возвратит ответы на его запросы. С какими проблемами вы можете столкнуться? С какими вещами следует проявлять осторожность? И как дизайн ваших форм изменится, принимая во внимание этот новый подход в программировании?

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

    РесурсыНаучиться
    • Оригинал статьи .
    • Adaptive Path – это одна из передовых компаний в области проектирования пользовательского интерфейса. Вы можете получить кучу информации по Ajax, внимательно исследуя их страницы. (developerWorks, октябрь 2005) демонстрирует пять путей сериализации данных в Ajax-приложениях. (O"Reilly Media, Inc., February 2006) берет идеи, выделенные в этой статье и всей серии, и предоставляет их (и много чего еще) вам в инновационном и передовом формате "Вперед головой".
    • JavaScript: Полное руководство , 4-я редакция (O"Reilly Media, Inc., ноябрь 2001) – отличный ресурс по языку JavaScript и работе с динамическими Web-страницами.
    Обсудить
    • Ajax.NET Professional - это отличных блог обо всем, что связано с Ajax.
    • Присоединяйтесь к сообществу developerWorks, участвуя в .

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

    Впервые об AJAX я услышал весной этого года. Сразу заинтересовался этой технологией, и, как и положено в таких случаях, отправился в поиск за статьями, которые смогли бы ответить на возникшие у меня вопросы: "Что это такое? Как это работает? И в чем преимущества? Что нужно дополнительно установить на сервер/клиент для работы с AJAX? Как это можно использовать на своем сайте?". Прочтя с десяток статей, я получил ответ лишь на первые два вопроса, но на остальные ответа так нигде не нашел. И лишь после прочтения нескольких публикаций на английском языке я окончательно понял, что к чему. Это и подвигло меня к написанию данного материала.

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

    По ходу изложения под термином "браузер" мы будем понимать браузеры: Internet Explorer 5.0+, Safari 1.3 и 2.0+, Netscape 7+, Opera 8.5+, Mozilla Firefox (плюс означает данную версию и более новые). Если речь станет заходить о других версиях, об этом будет упоминаться отдельно."Что это такое? Как это работает и в чем преимущества?"

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

    Пользователь в браузере открывает какую-либо страницу page . На странице есть гиперссылки, которые ведут на другие страницы. При нажатии на любую из них браузер посылает запрос URL на сервер, с которым связана эта ссылка. Если в природе не существует сервера, связанного с этой ссылкой (например, когда, набирая URL в адресной строке, вы ошиблись при написании имени ресурса), или имеются проблемы связи с интернетом, то браузер сгенерирует страницу, подобную показанной на картинке (так она выглядит в Operа-е):

    В случае существования сервера, но отсутствии на нем документа, указанного в запросе сервер сам создаст HTML страницу с описанием ошибки. Например, это может быть всем известная 404-ая ошибка (документ не найден). Или, если все верно, в ответ сервер отдаст новую страницу. В любом случае, в браузер будет загружена новая страница new_page, даже если по сравнению со старой на ней изменилась лишь пара слов. Довольно существенный минус данной технологии. Кроме того, работа ведется в синхронном режиме. То есть после того как браузер отослал на сервер запрос он ожидает от него ответ, и пока ответ не получен ничего предпринимать не будет. А порой ответ, и загрузка новой страницы может длиться слишком долго. Настолько долго, что пользователь может не дождаться загрузки страницы и просто закрыть её. Поэтому веб-программмисты прибегают к некоторым уловкам.

    СВОЙСТВА:

    readonly onreadystatechange function

    Указывает функцию обратного вызова (callback function), которая будет вызываться каждый раз, когда будет изменяться readyState свойство. Несмотря на то, что вызывается функция, параметры передать в нее не получиться. Но об этом чуть позже в примере.

    readonly readyState integer

    Состояние запроса. Может принимать значения:
    • 0 - не неинициализированный (uninitialized), метод open() еще не был вызван;
    • еще не вызван;
    • 2 - загружен (loaded), метод send() был вызван и ответные заголовки/статус (свойство status ) получены;
    • 3 - интерактивный (interactive), идет прием данных, которые доступны через свойство responseText ;
    • 4 - завершенный (completed), в ответ на запрос получены не только все заголовки и статус, но и приняты все данные от сервера, ответ завершен.

    readonly responseText string

    Ответ сервера в виде обыкновенного текста. Только чтение.

    readonly responseXML object

    Ответ сервера в виде объекта DOM Document. Используется, если ответ сервера является корректным XML документом. Если документ не корректный, данные не получены или еще не оправлены, то свойство равно NULL. Только чтение.

    readonly status string

    Статус ответа. Например: 200 (ОК), 404 (документ не найден), 503 (временная перегрузка сервера). МЕТОДЫ:

    void abort()

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

    string getAllResponseHeaders()

    Возвращает все заголовки ответа сервера в виде отформатированной строки. Каждый новый заголовок начинается с новой строки.

    string getResponseHeader (string header)

    Вернуть заголовок с именем header.

    void open (string method, string uri, [boolean asynch])

    Подготавливает запрос по адресу uri методом method (POST или GET) с указанием режима asynch, асинхронный режим или нет. В результате вызова свойство readyState становиться равным 1.

    void send (string data)

    Инициирует запрос к серверу. В запросе передаются данные data.

    void setHeader (string header, string value)

    Присваивает заголовку с именем header, значение value. Перед началом использования этого метода не забудьте вызвать open() ! "Как это можно использовать на своем сайте?"

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

    Итак, у нас задача: нужно реализовать базу данных (БД) драйверов для различных устройств. При этом БД настолько большая, что нет смысла пересылать её приложению-клиенту и делать выборку из неё посредством JavaScript. Из-за изменения одного значения на странице перегружать её тоже нежелательно. Лично я для реализации данной задачи применяю для серверных скриптов PHP, а реализации БД применяю XML файл.

    Структуру БД выбираю следующую:

    Листинг БД файл data.xml : ATI 9600 128 DDR (128bit) ATI 9600 256 DDR (128bit) ATI 9600XT 256 DDR (128bit) ATI X800GTO 256 DDR (256 bit) ATI X1300 512 DDR(128bit) ATI X1300 256 DDR (128bit) NVidia 6600 128 DDR (128bit) NVidia 7800GS 256 DDR (256 bit) ATI X1300Pro 256 DDR (128bit) ATI X1600Pro 256 DDR (128bit) ATI X1800GTO 256 DDR (256bit) ATI X1600Pro 256 DDR (128bit) ATI X1900XT 512 DDR (256bit) NVidia 6600 Silencer 128 DDR (128bit) NVidia 6600GT 128 DDR (128bit) ATI X1900XT 512 DDR (256bit) ATI X1900XTX 512 DDR (256bit) ATI X800 SilentPipe 128 DDR(256bit) Nvidia 6600GT 128 DDR (128bit) NVidia 6600GT PassiveHeatsink 128 DDR (128bit) PCI-E ATI X550 128 DDR (128bit) PCI-E ATI X800GT Uniwise 256 DDR (256 bit) ATI X800GTO 256 DDR (128bit) Audigy 2 6.1 Audigy 2 ZS 7.1 X-Fi Platinum Audiophile 192 Revolution 5.1 Audiophile Audiophile Fast Track PIXMA iP 90 PIXMA iP4200 PIXMA iP6600D Picture Mate 100 Stylus Color C48 Stylus Color C87U DeskJet 1280 DeskJet 5443 Photo Smart 385 Laser Shot LBP2900 Laser Shot LBP3300 ML 1615 ML 2015 LaserJet 1018 LaserJet 2420 LaserJet 2420DN 4200F LiDE500F LiDE60 Perfection 1270 Perfection 3590 Perfection 4990 Bear Paw 2400CU Perfection 4990

    Как в этой БД человек ведет поиск? Скорее всего, он от корневого элемента шел бы по дереву документа до тех пока в нужной ветви не нашел ссылку или убедился, что драйвера для данного устройства нет в базе. Также поступим и мы, используя для нахождения нужного узла или набора узлов выражения языка XPath .

    Листинг формы для отправки данных index.htm :

    видео картазвуковая картапринтерсканер

    В форме есть две переменные: path и flag . В первой хранится запрашиваемый путь, который отправляется на сервер. Так как один элемент в форме уже есть, то у этой переменной уже есть начальное значение. Вторая переменная служит для того, чтобы указать серверному скрипту, что из документа нужно извлечь определенный элемент Device . Кроме того, формат возвращаемых данных с сервера изменится.

    Теперь рассмотрим JS-движок. Все функции клиентской части собраны в скрипте ajax.js : y = new Object(); function httpRequest() { if (window.XMLHttpRequest) { //создание объекта для всех браузеров кроме IE requestObj = new XMLHttpRequest(); } else if (window.ActiveXObject) { //для IE requestObj = new ActiveXObject("Msxml2.XMLHTTP"); if (!requestObj) { requestObj = new ActiveXObject("Microsoft.XMLHTTP"); }; }; }; function sendRequest (url,data) { httpRequest(); //определяем call-back функцию requestObj.onreadystatechange = responseServer; //подготовка отправки данных, readyState=1 requestObj.open("POST",url,true); /* Т.к. данные отправляются POST методом, то необходимо серверу отослать заголовок информирующий его об этом */ requestObj.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8"); //отправка данных на сервер requestObj.send(data); }; function responseServer() { if (requestObj.readyState == 4) { var status = requestObj.status; if (status == 200) { addSelect(y); } else if (status == 400) { alert("Неправильный запрос"); } else if (status == 500) { alert("Внутреняя ошибка на сервере"); } else if (status == 503) { var time = requestObj.getResponseHeader("Retry-After")*1000; alert("Сервер перегружен. Запрос будет повторен через: "+time+" секунд"); setTimeout(sendRequest(url,path),time); } else { alert("Ошибочный ответ сервера"); }; }; }; function sendData(obj) { var Elpath = document.form.path; var url = "index.php"; if (document.form.flag.value == "0") { var path = Elpath.value + "/" + obj.value; } else { var path = Elpath.value + "/Device["" + obj.value + ""]"; /* методом GET отправляем серверному скрипту информация о том что необходим конкретный элемент Device */ url = "index.php?flag=1"; }; //присваиваем переменной формы path значение текущего запроса Elpath.value = path; //кодируем передаваемую строку path path = "path="+encodeURIComponent(path); y = obj; sendRequest (url,path); }; function addSelect(obj) { //ответ сервера в виде обычного текста var docTEXT = requestObj.responseText; obj.setAttribute("disabled",true); //создаем элемент div var div = document.createElement("div"); //добавляем ответ сервера в div div.innerHTML = docTEXT; //добавляем div с ответом сервера в дерево документа document.form.appendChild(div); }; function reset() { document.form.path.value="//Devices"; document.form.flag.value="0"; var NodeListDiv = document.form.getElementsByTagName("div"); var length = NodeListDiv.length; if (length > 1) { while (NodeListDiv != undefined) { document.form.removeChild(NodeListDiv); }; }; document.form.Devices.removeAttribute("disabled"); };

    Как я уже говорил, в функцию свойства onreadystatechange нельзя передать параметры. Точнее нельзя передавать параметры, которые являются объектами. Поэтому в самом начале создаем переменную, в которой и будем хранить ссылку на вызвавший функцию объект. Поскольку данная переменная находится в глобальной зоне видимости переменных, то обратиться к ней можно будет из любой части программы. На данный момент это самый разумный способ передать параметры call-back функции свойства onreadystatechange объекта.

    А теперь разберем по шагам работу движка.

    При наступлении события onblur (элемент select потерял фокус) вызывается функция sendData(), которая и подготавливает POST данные для оправки запроса. Кроме того, она формирует XPath выражение в зависимости от значения переменной flag=0 (например, //Devices/VideoCards ) или flag=1 (например, //Devices/VideoCards/AGP/Sapphire/Device["ATI 9600XT 256 DDR (128bit)"] ).

    Далее вызываем функцию sendRequest(), в которую передаем URL серверного скрипта, а также переменную типа строка, в которой содержатся готовые POST-данные. И первым делом создаем XMLHttpRequest объект, ссылку на который храним в переменной requestObj . Функция httpRequest() является кросс-браузерной, и будет работать во всех браузерах.

    Когда-то обращение к функции httpRequest() я делал сразу при загрузке страницы через и больше не создавал XMLHttpRequest объект. Но как оказалось, это работает для всех браузеров кроме IE, который каждый раз требует создавать новый объект. Поэтому вызов данной функции делается каждый раз перед отправкой данных.

    После отправки данных браузер ждет ответа с сервера. При каждом изменении свойства readyState будет вызываться функция responseServer() . Если статус ответа пришел с кодом "200" (все нормально), то будет вызвана функция addSelect(), которая и добавит полученный данные в DOM текущего документа. Все браузеры будут ждать ответа от сервера. Однако по истечении некоторого времени (time-out) принудительно назначат XMLHttpRequest.readyState = 4 и перестанут ожидать ответа с сервера. Например, для Opera значение тайм-аута составляет 10 секунд. Используя другие статусы, можно добавить в движок обработчик ошибок в ответах сервера.

    Функция addSelect() добавляет в DOM текущего документа еще один узел DIV, в который и помещает ответ с сервера. Может возникнуть вопрос, почему используется свойство responseText , а не responseXML ? У кого-то обязательно возникнет желание, используя это свойство, импортировать ответ сервера (а серверный скрипт в ответ присылает XML документ) прямо в DOM документа. Возникло такое желание и у меня. Я хотел импортировать корневой элемент присланного XML файла и все его потомки методом importNode . Но браузер импортировал элемент без потомков, даже несмотря на то, что второй параметр данного метода был установлен в true : importNode(Object importedNode,true) . Поэтому не точная реализация этого метода пока исключает его использование.

    Равнозначное решение было найдено, используя innerHTML метод элемента.

    На этом работа клиентской части заканчивается. Оставшаяся нерассмотренной функция reset() призвана вернуть DOM документа к начальному виду. Достичь того же можно, обновив страницу по F5, но AJAX-движок как раз и пишется для того, чтобы избежать перезагрузки страницы. Поэтому все элементы, добавленные в документ скриптом, должны быть удалены из него также скриптом.

    В ответ на запрос серверный скрипт формирует XML данные вида: childrenElementName_1 .... childrenElementName_1

    Если запрашиваемый узел имеет имя Device , то возвращается обычный отформатированный текст. Серверный скрипт написан на PHP V5 и не будет работать на более ранних версиях этого интерпретатора, так как расширение для работы с DOM было введено в этот язык только с пятой версии, и заменило собой расширение DOM XML, интерфейс которого не соответствовал спецификации. А теперь посмотрим на код серверного скрипта.

    Листинг файла index.php : load("data.xml"); //создаем объект XPath $DOMXPath = new DOMXPath($doc); $DOMNodeList = $DOMXPath -> query($_POST); //согласно запросу извлекаем нужный элемент $DOMNode = $DOMNodeList -> item(0); //создаем объект XML-документ $replyXML = new DOMDocument("1.0", "windows-1251"); /* если flag не равен единице, значит текущий элемент не является элементом Device и необходимо найти все элементы-потомки текущего элемента DOMNode */ if ($_GET != 1) { //получаем список все потомков элемента $childNodes = $DOMNode -> childNodes; /* Поскольку потомки могут быть не только элементы, но и узлы, то создаем индексный массив который содержит только элементы-потомки */ foreach ($childNodes as $Node) { if ($Node->nodeType == 1) { $arrayNodes = $Node; }; }; //создаем корневой элемент XML-документа $root = $replyXML->createElement("select"); $optgroup = $replyXML->createElement("optgroup"); /* если элементы-потомки не являются Device, то задаем атрибуты для корневого элемента и его элемента-потомка optgroup */ if ($arrayNodes -> nodeName != "Device") { $root->setAttribute("name",$DOMNode->nodeName); $AttributeNode = $arrayNodes->getAttributeNode("title"); $optgroup->setAttribute("label",$AttributeNode->value); $root->setAttribute("onblur","sendData(this)"); } else { /* в противном случае создаем атрибут с JS кодом который и присвоит переменной в форме flag значение "1" */ $root->setAttribute("onblur", "document.form.flag.value=1;sendData(this);"); }; /* цикл создающий для каждого элемента-потомка новые элементы option; сколько потомков, столько и элементов */ foreach ($arrayNodes as $Node) { $option = $replyXML->createElement("option"); $setNode = $Node->nodeName; if ($Node->nodeName == "Device") { $setNode = $Node->nodeValue; }; $option-> nodeValue = $setNode; $option->setAttribute("value",$setNode); $optgroup->appendChild($option); }; //вставляем в XML-документ получившиеся элементы $replyXML->appendChild($root); $root->appendChild($optgroup); /* если flag=1, то значит текущий элемент является Device элементом; элементы-потомки не нужны, а нужны атрибуты текущего элемента */ } else { //создаем корневой элемент $root = $replyXML->createElement("pre"); $DOMText = new DOMText(" OS URL"); $root -> appendChild($DOMText); $NamedNodeMapAttr = $DOMNode->attributes; $i = 0; /* цикл который находит все атрибуты элемента Device и для каждого атрибута создает строку с данными содержание ссылку */ while (($NodeAttr = $NamedNodeMapAttr->item($i)) != null) { if ($NodeAttr->name != "id") { $DOMText = new DOMText(" $NodeAttr->name "); $DOMElement = $replyXML->createElement("a"); $DOMElement -> setAttribute("href",$NodeAttr->value); $DOMElement -> nodeValue = $NodeAttr->value; $root -> appendChild($DOMText); $root -> appendChild($DOMElement); }; $i++; $NodeAttr = $NamedNodeMapAttr->item($i); }; $replyXML->appendChild($root); }; //отсылаем ответ клиенту echo $replyXML->saveHTML(); ?>

    Лучшие статьи по теме