2 Авг
Что такое AJAX, думаю, все уже знают и имеют небольшое представление о том, как он работает. Но всё же много людей до сих пор представления не имеют о том, каким боком собственно XML, так как большинство ресурсов расписывают работу только со свойством responseText, не говоря уже о сторонних библиотеках (prototype, sAjax и прочее).
Некоторые люди говорят, что AJAX прозвали именно AJAX’ом потому что это «прикольно». Цитата: «У американцев есть манечка, придумывать красивые аббривиатуры, они ведь не назовут технологию AJAT(response text), AJAX звучит на порядок лучше». Но это не так. Технология AJAX действительно придумана и разработана для работы с XML данными.
XML (EXtensible Markup Language) - разработан для хранения и передачи данных. Очень простой в изучении и использовании язык разметки. В настоящее время нашел широкое применение в прикладном программировании, особенно после выпуска Microsoft Visual Studio 8 и 9 (xml manifest, config, и т.д.). Есть несколько ресурсов, которые вообще отказались от HTML, CSS и полностью перешли на XML. Сразу возникает вопрос? А как же визуальная разметка? Здесь, на помощь приходит XSLT – EXtensible Stylesheet Language. Но в нашем случае вещь бесполезная, так как мы будем внедрять XML данные в уже оформленный HTML документ.
Надеюсь все уже догадываются о том, что суть AJAX в использовании нестандартного объекта – XMLHttpRequest, для общения со сторонними ресурсами. Итак, начнем с универсальной функции для создания xmlHttp объекта в различных браузерах. Выглядит она примерно так:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | function getXmlHttp(){ var xmlhttp; try { xmlhttp = new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) { try { xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); } catch (E) { xmlhttp = false; } } if (!xmlhttp && typeof XMLHttpRequest != 'undefined') { xmlhttp = new XMLHttpRequest(); } return xmlhttp; } |
Сам объект XMLHttpRequest понимают только Firefox, Opera 8+ и Safari, так что для вредного ослика мы будем использовать его ActiveX объект, который имеет те же методы что и XMLHttpRequest. Кстати, компания Microsoft – первый, кто представил такой объект, а Firefox, Opera, Safari и другие браузеры последовали.
В рамках данной статьи мы будем использовать запрос с методом GET. Делается это в две строки, не считая инициализацию объекта xmlHttp:
var xmlHttp; xmlHttp = getXmlHttp(); xmlHttp.open('GET', 'http://www.example.ru/data.xml', true); xmlHttp.send(null)
Где http://www.example.ru/data.xml сторонний ресурс содержащий XML данные. НО, прежде чем отсылать куда-то запрос, советую сразу установить «слушатель» для данного объекта. «Слушатель» устанавливается таким образом:
xmlHttp.onreadystatechange = nameOfFunction;
Где nameOfFunction – имя функции которую следует вызвать при смены состояния объекта xmlHttp. Список всевозможных состояний:
Следовательно, откликаться мы будем только по состоянию 4 – готово.
function nameOfFunction() { if (xmlHttp.readyState == 4) { // что нибудь делаем } }
То же самое можно написать и в одном блоке:
xmlHttp.onreadystatechange = function() { if (xmlHttp.readyState == 4) { // что нибудь делаем } }
Далее следует проверить полученный код статуса HTTP сервера, но это не в рамках нашего сюжета. Сконцентрируемся на XML.
К полученным данным вы можете получить доступ двумя способами:
Нас, в данном случае, интересует только второй способ. Делается это вот таким образом:
var xmlDoc = xmlHttp.responseXML.documentElement;
xmlHttp.responseXML.documentElement – это объект содержащий весь, полученный XML документ. Теперь нам следует его обработать, то есть «выдернуть» из негу нужную нам информацию, в нужном нам порядке. Для этого мы будем использовать методы DOM (Data Object Model), а именно getElementsByTagName(). В цикле по главному (не путать с корневым) элементу XML документа мы можем пройти через все интересующие нас записи. Для примера рассмотрим простой XML документ:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <?xml version="1.0" encoding="windows-1251"?> <newsarchive> <entry> <id>73</id> <title>заголовок первой статьи</title> <content>содержание первой статьи</content> <date>2008-03-04 05:03:24</date> </entry> <entry> <id>74</id> <title>заголовок второй статьи</title> <content>содержание второй статьи</content> <date>2008-03-10 15:21:39</date> </entry> </newsarchive> |
Пускай это будет простой новостной архив из 2х записей. Таким образом, главным нашим элементом будет являться элемент entry, так как он и содержит несущую смысл информацию. На самом деле всё зависит от структуры документа, его элементной вложенности. XML позволяет писать какие угодно тэги, какой угодно вложенности, так что структура остаётся на усмотрение самого автора.
Вернемся к нашему XML документу. Мы будем просматривать каждый элемент entry в цикле, а данные элемента (id, title, content, date) будем добавлять (appendChild) в определенном порядке к какому-либо объекту, например data_div (document.getElementById). Примерно так:
1 2 3 4 5 6 7 8 9 | var xmlDoc = xmlHttp.responseXML.documentElement; var dataArray = xmlDoc.getElementsByTagName("entry"); obj = document.getElementById("data_div"); for (var i = 0; i < dataArray.length; i++) { var new_el = document.createElement("div"); new_el.innerHTML = '<b>' + xmlDoc.getElementsByTagName("title")[i].childNodes[0].nodeValue + '</b><br>' + xmlDoc.getElementsByTagName("date")[i].childNodes[0].nodeValue + '<br>' + xmlDoc.getElementsByTagName("content")[i].childNodes[0].nodeValue + '<br><br>'; obj.appendChild(new_el); } |
Итак, какой-нибудь HTML документ, который будет обращаться к XML файлу за данными. В нём div куда будут добавляться данные, и ссылка для посылки запроса:
<div id="data_div">
<a href="#" onclick="getSomeData(); return false;">получить данные</a><br>
</div>Javascript функция getSomeData():
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | function getSomeData() { var xmlHttp; xmlHttp = getXmlHttp(); xmlHttp.onreadystatechange = function() { if (xmlHttp.readyState == 4) { var xmlDoc = xmlHttp.responseXML.documentElement; var dataArray = xmlDoc.getElementsByTagName("entry"); obj = document.getElementById("data_div"); for (var i = 0; i < dataArray.length; i++) { var new_el = document.createElement("div"); new_el.innerHTML = '<b>' + xmlDoc.getElementsByTagName("title")[i].childNodes[0].nodeValue + '</b><br>' + xmlDoc.getElementsByTagName("date")[i].childNodes[0].nodeValue + '<br>' + xmlDoc.getElementsByTagName("content")[i].childNodes[0].nodeValue + '<br><br>'; obj.appendChild(new_el); } } } xmlHttp.open('GET', 'data.xml', true); xmlHttp.send(null); } |
XML документ data.xml (повторно):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <?xml version="1.0" encoding="windows-1251"?> <newsarchive> <entry> <id>73</id> <title>заголовок первой статьи</title> <content>содержание первой статьи</content> <date>2008-03-04 05:03:24</date> </entry> <entry> <id>74</id> <title>заголовок второй статьи</title> <content>содержание второй статьи</content> <date>2008-03-10 15:21:39</date> </entry> </newsarchive> |
AJAX, чаще всего, работает с динамическими данными. Возможно ли динамически подавать XML документ? Конечно, любой серверный язык может выдать документ в виде XML, а в функцию xmlHttp.open() спокойно можно подставить data.php вместо data.xml. Главное помнить об одном – некоторые браузеры (в частности Internet Explorer) воспринимают XML файл только тогда, когда он действительно XML файл. То есть в вашем серверном скрипте нужно обязательно выслать заголовок браузеру, о том что вывод – XML. Конкретнее на примере PHP:
header('Content-type: application/xml');
Вы так же можете воспользоваться javascript функцией:
xmlHttp.overrideMimeType('application/xml');
Отзывов (12) на «AJAX и собственно XML»
21.09.2008 в 20:58
1
честно скажу нифига ничего непонял =)))…ну преlставь себя на моем месте ..я человек который изучает php и решил поучить ajax ….как ты думаешь я тут что нибудь понял? Друг прошу тебя давай прощееееее!!!! =)
23.09.2008 в 08:40
2
:) Сочувствую, но проще помоему уже некуда.. Если вы только изучаете php то советую не лезть пока в ajax, а вот когда вы будете хорошо ориентироваться в php тогда можно и приступать :) удачи!
25.09.2008 в 16:51
3
Маленькая проблемка ваш код не работает в IE поскольку методы:
getElementsByTagName(”title”)[i].childNodes[0].nodeValue
//в експлорере имеют другой синтаксис.
Попробуйте сделать жемку с вашего примера и выложить что бы можно было людям убедиться что в все окей точно во всех браузерах.
29.09.2008 в 06:52
4
Сергей, а помоему всё работает: AJAX + PHP поиск :\
14.10.2008 в 15:14
5
А эта форма тоже с помощью аякса работает?
14.10.2008 в 15:18
6
Андрей, да нет, не особо ;)
04.12.2008 в 12:27
7
Форма не работает ни в каком браузере.
Даже если в php просто выдавать готовый ответ echo’м
06.12.2008 в 00:19
8
Sad, странно, вы единственный у кого не заработало ;)
18.12.2008 в 11:01
9
Спасибо, хорошая и полезная статья:)
18.12.2008 в 13:37
10
MAH69K, не за что, вам спасибо - хороший и полезный комментарий :))
06.01.2009 в 12:32
11
Все хорошо, но на IE не работает.
выдает ошибку c00ce56e? и че-то танцы с бубном не помогают (я про кодировку).
06.01.2009 в 15:13
12
Дмитрий, возможно это в настройках IE, ибо worksforme ;)
Оставьте отзыв