AJAX. Основы.

AJAX (аякс) — это web технология, позволяющая взаимодействовать с сервером без перезагрузки страницы. Примерами применения служат проверка имени пользователя на занятость при регистрации, отправка товара в корзину без перезагрузки, google suggest
и т.д. AJAX базируется на объекте XMLHttpRequest. Как видно из названия он задумывался для работы с XML, что, впрочем, не мешает использовать его и в других целях.

Принцип работы следующий: скрипт состоит из двух частей

  1. клиентская часть: исполняется на стороне клиента, пишется на JavaScript
  2. серверная часть: исполняется на сервере, может быть написана на любом языке программирования, понимающем GET/POST запросы

Этапы написания клиентской части:

  1. сбор и подготовка информации для отправки запроса на сервер;
  2. создание экземпляра объекта XMLHttpRequest;
  3. установка для него функции обработчика события onreadystatechange. Это событие наступает при каждой смене состояния объекта XMLHttpRequest (см. таблицу внизу). Данная функция по сути является основной частью скрипта, поскольку именно в ней происходит обработка ответа сервера;
  4. открытие соединения с указанием типа запроса (GET или POST), URL серверной части, флага асинхронного режима и имени и пароля пользователя (если необходимо);
  5. непосредственно отправка запроса;
  6. обработка ответа серверной части.

Создание объекта XMLHttpRequest отличается для Internet Explorer и других обозревателей, поэтому для совместимости эту операцию приходиться дублировать разными способами:

var req;

if (window.XMLHttpRequest)	// normal browser
    req = new XMLHttpRequest();
else if (window.ActiveXObject) {	//IE
    try {
        req = new ActiveXObject('Msxml2.XMLHTTP');  // IE разных версий
    } catch (e){}									// может создавать
    try {											// объект по разному
        req = new ActiveXObject('Microsoft.XMLHTTP');
    } catch (e){}
}

Использование метода GET, установка обработчика события onreadystatechange и отправка запроса:

req.open("GET", url, true);
req.onreadystatechange = function() {
	if (req.readyState == 4)  { обработка результатов }
};
req.send(null); //отправка запроса без параметров, т.к. они установлены в url

В обработчике события onreadystatechange необходимо обязательно проверить условие req.readyState == 4, которое говорит о том, что данные загружены. Дополнительно можно также проверять req.status == 200. См. таблицы ниже.

При использование объекта XMLHttpRequest с методом POST требуется дополнительно отправлять header:

req.open("POST", url, true);
req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
req.onreadystatechange = function() {
   if (req.readyState == 4)  { обработка результатов }
};
req.send('param1=1¶m2=0'); //теперь параметры передаются здесь

Несколько параметров разделяются амперсандами.

Полный пример:

var req;

if (window.XMLHttpRequest) req = new XMLHttpRequest();
else if (window.ActiveXObject) {
    try {
        req = new ActiveXObject('Msxml2.XMLHTTP');
    } catch (e){}
    try {
    req = new ActiveXObject('Microsoft.XMLHTTP');
    } catch (e){}
}

if (req) {
    req.onreadystatechange = function() {
    	if (req.readyState == 4 && req.status == 200)  { alert(req.responseText); }
    };
    req.open("POST", 'xmlhttp.php', true);
    req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
    req.send('param=1&ajax=1');
}
else alert("Браузер не поддерживает AJAX");

Серверная часть (url в req.open) может быть написана на чем угодно, лишь бы понимала запросы GET/POST. Возращаемое значение (req.responseText) формируется стандартным выводом.

Пример серверной части на php:

if(isset($_POST['param']))
echo ($_SERVER['REMOTE_ADDR'])?"Your IP ".$_SERVER['REMOTE_ADDR']:"IP неизвестен";

Немного справочных материалов:

Методы класса XMLHttpRequest

Метод Описание
abort() отменяет текущий запрос
getAllResponseHeaders() возвращает полный список HTTP-заголовков в виде строки
getResponseHeader(headerName) возвращает значение указанного заголовка
open(method, URL, async, userName, password) определяет метод, URL и другие опциональные параметры запроса; параметр async определяет, происходит ли работа в асинхронном режиме
send(content) отправляет запрос на сервер
setRequestHeader(label, value) добавляет HTTP-заголовок к запросу
overrideMimeType(mimeType) позволяет указать mime-type документа, если сервер его не передал или передал неправильно. Внимание: метод отсутствует в Internet Explorer!

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

Свойство Описание
onreadystatechange обработчик события, которое происходит при каждой смене состояния объекта
readyState возвращает текущее состояние объекта (0 — неинициализирован, 1 — открыт, 2 — отправка данных, 3 — получение данных и 4 — данные загружены)
responseText текст ответа на запрос
responseXML текст ответа на запрос в виде XML, который затем может быть распарсен посредством DOM
status возвращает HTTP-статус в виде числа (404 — «Not Found», 200 — «OK» и т. д.)
statusText возвращает статус в виде строки («Not Found», «OK» и т. д.)

46 Комментарии “AJAX. Основы.

  1. Привет!Сперва о хорошем — Отличный ресурс.Теперь о плохом. Приведенный пример у меня заработал только на Опере 9.27. FF2.0, ie6, ie7, safari3.1.1 выдали ошибку.

  2. Да, спасибо за своевременный сигнал. Исправил.Дело в том,
    что был изменен DOCTYPE страницы, а в XHTML вот такая конструкция req.open("POST", '', true);
    кроме Оперы нигде не проходит, то есть пустая ссылка не указывает сама на себя и возникает красноречивая
    ошибка uncaught exception: [Exception… "Component returned failure code: 0x80070057
    (NS_ERROR_ILLEGAL_VALUE) [nsIXMLHttpRequest.open]" nsresult: "0x80070057
    (NS_ERROR_ILLEGAL_VALUE)" location: "JS frame :: javascript: eval(__firebugTemp__); ::
    anonymous :: line 1" data: no]
    .

  3. Спасибо. Буду дерзать. После бездарной книжки начал-было склоняться к мысли, что я слабоумен, так там замечательно описано было…

  4. Привет!Не будет ошибкой использование responseText до открытия и отправки параметров? Пока не понял этого.

  5. использование responseText до открытия и отправки параметров не имеет смысла, поскольку responseText это ответ серверной части на ajax запрос, поэтому до отправки параметров он не определен

  6. Ну так и я об этом:req.onreadystatechange = function() { if (req.readyState == 4 && req.status == 200) {alert(req.responseText);} // здесь }; req.open("POST", ‘ajax/ajax_fundamentals.php’, true); req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); req.send(‘param=1’); // и здесь

  7. В строках, приведенных вами выше, назначается функция-обработчик события. Это событие и есть ответ сервера, т.е. responseText до открытия и отправки параметров не используется

  8. То есть, onreadystatechange следит за состоянием всё время, и неважно, где он стоит? И всё же, почему не поставить обработчик после отправки? Спасибо.

  9. Он не все время следит, а вызывается только после совершения события. Это как onclick или onmouseover. Если его поставить после отправки, то получится, что событие не знает какая функция должна его обработать…

  10. Читаю и ничего не могу понять, посоветуйте какие нибудь книги по этому делу

  11. Огромное спасибо, вот по этой статье я научился Ajax…

  12. Немогу понять вчем дело (
    У меня Linux + Firefox 3.0.3 (пробовал так же 3.0)
    Данный пример в нем УЖЕ не работает (
    У меня собственный кусок кода на аякс, в опере и второй Лисе — порядок. А с 3ей версии начал выдеылываться. немогу понять вчем проблема.
    У меня должна отправляться форма на сервер, но увы.. (

  13. Для меня так проще jqueryвский .ajax(). Неохота на низкий уровень лезть.

  14. Здравствуйте Автор! Это действительно доступная в понимании и полезная инфа, для тех кто начинает осваивать такого рода программирование. Я до этого находил примеры такого типа но они у меня не работали. Данный пример работает, но к сожалению в IE7 (будь он проклят) почему то не хочет. я заключил верхний код обработчик в < script > function myajax () { код }< / script > а нижний код серверную часть как и полагается в файл xmlhttp.php сделал гиперссылку для вызова функции < a onclick = " myajax ( ) " текст < / a > IE видит в строке выше какую-то ошибку, что там ни так?

  15. Интересно. >"Если вы видите это сообщение — значит вы используете браузер Internet Explorer…." У меня вообщето Mozilla/5.0 (Windows; U; Windows NT 5.1; ru; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5

  16. Спасибо за материал! А я-то поступил именно так, как вы описали здесь: http://easywebscripts.net/ajax/ajax_books.php и даже скачал именно ту самую книжищу. И реакция у меня примерно такая же была: "зачем столько воды???" Еще раз спасибо!

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

  18. Спасибо огромное отличная статья и сайт!

  19. Огромное спасибо за статью. Сберегли мне уйму времени!

  20. ///// req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); var param = 2; req.send('param=2'); } ///// а как вместо 'param=2' поставлять переменную… не могу понять почему не полчается =(

  21. to Kuli передать переменную … var x = 5; xmlHttp.send('x='+x); … на стороне сервера принять переменную и передать обратно $x = $_POST['x']; $x = $x+1; echo("x = ". $x); Сайт мне очень понравился! Все кратко, ясно и по делу! Спасибо=)

  22. Подскажите, возможно ли получить от сервера несколько ответов, то есть : $x = $_POST['x']; $x = $x+1; echo("x = ". $x); // первый ответ echo("y = ". $x+2); // второй ответ при этом не отправляя всего один запрос

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

  24. Можно вопрос? к автору …& req.status == 200) {alert(req.responseText);} |Этот код отрабатывает нормально| А если его заменить на: …& req.status == 200) {document.write(req.responseText);} То здесь, есть нюансы с работой некоторых обозревателей ~ 1) Chrome выдает результат сразу. 2) Opera ждет 1-2 секунды и записывает результат. 3) Firefox сразу записывает и находится в таком состоянии, как будто он, что-то еще загружает? (бесконечно долго) при alert этого не происходит, но при document.write — происходит задержка, или непонятные `Загрузка`

  25. Я использую innerHTML для отображения. А так, в целом, разобрался, автор, пиши еще!

  26. хедеры тоже выводились по началу) Только потом я понял, что нужно Ajax и PHP по разным файлам разделить : )

  27. Добавляю в скрипт строку типа document.getElementById('someDiv').innerHTML = req.responseText; тогда ответ скрипта на сервере выводится в этом div

  28. Рад что нашол ваш сайт! Очень толково все расписано и как раз, то чего я хотел, но боялся спросить )) Отключил нахер Адблок+ и нажал на ссылку )) Спасибо!

  29. Если все написано на php, то как передать параметр из php кода в req.send('param=1&ajax=1'); вместо param=1, param=(например $id).

  30. Так вот он, великий и ужасный AJAX… пишем обращение из джаваскрипта к пхп скрипту и получаем ответ, вот и всё, а я-то думал! Спасибо автору большое

  31. в вин 7 хоме едитионе в интернут эксплорере выдается ошибка — отказано в доступе. в вин7 ультимате уак я отключил и ноу трабл. как решить проблему?

  32. Автор, спасибо, я прозрел! Напишите, пожалуйста, можно ли передавать массивы методом POST, и как передавать картинки? Как только получить информацию, без передачи конкретных параметров?

  33. Это правда, что аякс можно использовать с jquery и это намного удобнее, чем вышеописанный метод?

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

  35. Автор, стать просто супер. Не скажу, что она помогла мне, но явно пользы больше чем от книги. Спасибо огромное )

  36. Здравствуйте. Прошу помочь — куча ресурсов пересмотрел по ajax но так ничего и не получается. Создал в одной папке файлы try.html и xmlhttp.php .В первом файле html код — в head-е функция вызова ajax скопированная с этой статьи, ну и в body кнопка с onClick вызовом этой функции. Перезагрузил локальный сервер, обновляю try.html — кликаю по кнопке — никакой реакции… вывожу свойства req.readyState (оно равно 4), и свойство req.status (оно почему-то равно 0). Нигде не нашёл что означает 0. Подскажите в чем может быть проблема.

  37. Подскажите в чем может быть причина, у меня не работает POST запрос, GET проходит нормально, а в POST при req.readyState == 4 req.status равен 0.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *