Технология ajax ее назначение и принцип работы. WEB-дизайнТехнология AJAX - изучаем Ajax на примере

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

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

По ходу изложения под термином "браузер" мы будем понимать браузеры: 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(); ?>

Сейчас в сети Интернет наблюдается очень активное развитие (и даже использование) новых технологий. Одна из таких технологий — 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 и произвести с ним необходимые операции. Помните, что такая передача данных и выполнение их не являются безопасными. Вы должны следить за тем, что поступает на исполнение.

    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, можно использовать любой другой серверный язык программирования.

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

    Приступим! Обратите внимание: предполагается, что вы уже знаете базовые front-end технологии, такие как HTML и CSS.

    Что такое AJAX?

    AJAX расшифровывается как «Асинхронный JavaScript и XML». Под AJAX понимается не одна технология, и она не является новой. На самом деле это группа технологий (HTML, CSS, Javascript, XML, и т.д.), которые связываются вместе для создания современных веб-приложений.

    С помощью AJAX клиент (браузер) общается с сервером и запрашивает у него данные. Полученный ответ обрабатывается, и в станицу вносятся изменения без полной ее перезагрузки. Разберем аббревиатуру AJAX:

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

    «JavaScript» это язык программирования, который используется для создания объекта запроса AJAX, парсинга этого ответа и обновления DOM страницы.

    Для отправки запроса на сервер клиент использует XMLHttpRequest или XHR API. API (программный интерфейс) это набор методов, которые задают правила общения между двумя заинтересованными сторонами. Тем не менее, приходящие из AJAX запроса данные могут быть в любом формате, а не только в XML.

    Как работает AJAX

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

    На картинке описан стандартный AJAX сценарий:

    Пользователь хочет увидеть больше статей, и он или она кликает на нужную кнопку. Данное событие запускает вызов AJAX.

    Запрос посылается на сервер. С запросом можно передать различные данные. Запрос может посылаться в статический файл (к примеру, example.php), хранящийся на сервере. Также можно выполнять динамические скрипты (functions.php), на каждом этапе которых будет происходить общение с базой данных (или другой системой) для извлечения необходимой информации.

    База данных отсылает обратно запрошенные статьи на сервер. А сервер посылает их в браузер.

    JavaScript парсит ответ и обновляет часть DOM (структура страницы). В нашем примере обновится только сайдбар. Остальные части страницы не меняются.

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

    Живой пример на AJAX

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

    Сперва рассмотрим принципы работы Facebook и Twitter. При прокрутке страницы вниз AJAX подгружает новый контент. Также если вы ставите лайк или дизлайк вопросам и ответам на Stack Overflow, опять же срабатывает AJAX. Как только вы вбиваете в строку поиска что-то в Google или Youtube, срабатывают множественные запросы AJAX.

    Более того, если мы захотим, то сможем отслеживать данные запросы. К примеру, в консоли Chrome это можно сделать, кликнув правой кнопкой мыши и активировав функцию Log XMLHttpRequests.

    Как создать запрос

    Выше мы уже говорили, что для создания запроса используется XMLHttpRequest API. Кроме того в jQuery, самой популярной JS библиотеке есть различные Ajax функции и методы. В серии статей мы рассмотрим различные примеры на чистом JS и JQuery для отправки запросов на сервер.

    Управление запросами

    Вытаскиваемые данные с сервера могут храниться в различных форматах. XML, JSON, JSONP, обычный текст и HTML.

    XML

    XML (Расширяемый язык разметки) – один из самых популярных форматов для обмена данными между приложениями. Формат похож на HTML, и в качестве структуры используются теги. Однако в XML нет готовых тегов, мы сами задаем их. Пример структуры ниже:

    Mike Mathew Australian English Spanish French Russian

    < person >

    < name > Mike < / name >

    < surname > Mathew < / surname >

    < nationality > Australian < / nationality >

    < languages >

    < language > English < / language >

    < language > Spanish < / language >

    < language > French < / language >

    < language > Russian < / language >

    < / languages >

    < / person >

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

    JSON

    JSON (JavaScript Object Notation) – еще один популярный формат обмена данными. В JSON пример сверху будет выглядеть так:

    { "name" : "Mike", "surname" : "Mathew", "nationality" : "Australian", "languages" : ["English", "Spanish", "French", "Russian"] }

    "name" : "Mike" ,

    , JSON Editor Online

    В JSN редакторе наш пример будет выглядеть так:

    Ограничения в AJAX запросах

    Перед тем, как начать использовать AJAX, необходимо узнать про ограничения. Мы рассмотрим только две проблемы.
    Первая – ошибка в консоли Chrome:

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

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

    Один из способов это CORS от W3C. Но данный механизм требует внести изменения в конфигурацию файлов на сервере. К примеру, на данной странице описано, как настроить Apache сервер. Другой способ это JSONP (JSON с набивкой).

    Заключение

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