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&param2=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» и т. д.)

 

Оцените статью
Добавить комментарий

  1. Evgen

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

  2. Alek Veritov

    Да, спасибо за своевременный сигнал. Исправил.Дело в том,
    что был изменен 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. Dimko

    Просто и понятно. Спасибо!

  5. Прим Палвер

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

  6. Alek Veritov

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

  7. Прим Палвер

    Ну так и я об этом: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’); // и здесь

  8. Alek Veritov

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

  9. Прим Палвер

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

  10. Alek Veritov

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

  11. Александр

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

  12. @KIMMI

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

  13. anonymous

    Ogromnoe spasibo ochen poleznaya infa…
    iz Yerevana..

  14. ll

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

  15. wzonnet

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

  16. KVANT

    Статья действительно хорошая, однако не раскрывает некоторые моменты, о которых более подробно написано тут http://www.ibm.com/developerworks/ru/library/wa-ajaxintro1/#code7

  17. nik0g0r

    великое cпасибо за азы…

  18. bushstas

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

  19. Я

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

  20. Опять Я

    За статью Спасибо

  21. Polo

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

  22. vova

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

  23. Ринат

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

  24. silver_11

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

  25. Kuli

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

  26. mov

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

  27. serg

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

  28. Алекс

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

  29. Euphoria

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

  30. Алекс

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

  31. Euphoria

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

  32. Euphoria

    Алекс, а как вы используете это с innerHTML?

  33. Алекс

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

  34. dummy n00b

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

  35. Дмитрий

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

  36. alta1r

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

  37. Anonymous

    Замечательная статья. Автору респект.

  38. Лекс

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

  39. Иван

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

  40. Николай

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

  41. ВиНТ

    Модно говорить: "аджакс" 😀

  42. Leo

    Спасибо, чуть было не скачал себе книгу.

  43. Волк

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

  44. товарищ Сталин

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

  45. Владимир

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

  46. Сергей

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