Контакты

Использование Ajax. JavaScript - Асинхронные AJAX запросы на примерах Запрос html-данных с помощью функции Load

Во всех четырёх статьях серии "Ajax на практике", мы разбирались, как использовать эту технологию с помощью библиотеки jQuery и, в частности, её метод $.ajax() , но всегда ли нужно прибегать к помощи фреймворков? К примеру, если в своём проекте, вы больше нигде не используете библиотеку, то абсолютно не резонно нагружать страницы лишними килобайтами и особенно, если этих килобайт около девяноста. Вывод - пишем ajax-запрос на чистом JavaScript, тем более, что та же библиотека jQuery, ни что иное, как подготовленный набор методов (функций ), написанный на нативном JS. Если взять для сравнения JS-код из статьи "Получение данных из формы ", то переписывая код, нам нужно будет сделать следующее:

  • Дождаться загрузки всего документа
  • Получить в распоряжение элемент
  • Повесить на него обработчик события submit
  • Подготовить данные формы на отправку
  • Создать объект XMLHttpRequest
  • С помощью XHR отправить данные
  • Получить, обработать и вывести на экран ответ сервера
  • Поехали пошагово...
    1) Вместо привычных $(function(){}) или $(document).ready(function(){}), устанавливаем свой обработчик события onload . Но прежде, хочу пояснить, почему мы не будем использовать конструкцию element.onevent = func; . Это способ хоть и кроссбраузерный, но главным его недостатком является то, что установив на один элемент два и более обработчика, последний "затрёт" предыдущие и они "не откатают свою обязательную программу". Поэтому, хоть кода на пару строк получится больше, но запишем так:

    // функция кроссбраузерной установки обработчиков событий function addEvent(elem, type, handler){ if(elem.addEventListener){ elem.addEventListener(type, handler, false); } else { elem.attachEvent("on"+type, handler); } return false; } // Вешаем обработчик события загрузки документа - DOM-Ready addEvent(window, "load", init);

    После загрузки документа, будет вызвана функция init , где мы сможем получить доступ к нашей форме. Этот шаг можно и пропустить, если весь js-код, будет расположен в самом конце документа, перед закрывающим тего , но случаи бывают разные...
    2) В функции init, мы обращаемся к нашей форме и, в свою очередь, устанавливаем на неё обработчик события submit.

    // Инициализация после загрузки документа function init(){ output = d.getElementById("output"); // элемент, куда мы выведем полученный в ответе результат myform = d.getElementById("my_form"); // форма addEvent(myform, "submit", sendAjaxRequest); // устанавливаем на форму обработчик события submit return false; }

    По событию submit, будет вызвана функция sendAjaxRequest. И сразу же переходим к этой функции, где сформируем данные формы для запроса и отправим ajax-запросом. Сформировать данные можно или с помощью объекта FormData , с которым вы могли познакомится (если до этого не были знакомы ) в статье "Получение данных из формы ", или же обращаться к каждому элементу формы, получая значения, по какому-нибудь его селектору, или пробежаться по элементам формы в цикле. Но прежде всего, нам нужно отменить обычное поведение формы на событие submit:

    // Функция Ajax-запроса function sendAjaxRequest(e){ var evt = e || window.event; if(evt.preventDefault){ evt.preventDefault(); // для нормальных браузров } else { evt.returnValue = false; // для IE старых версий } // ..... }

    В этой же функции, собираем все данные формы:

    // формируем данные формы var elems = myform.elements, // все элементы формы url = myform.action, // путь к обработчику (берём из атрибута action нашей формы) params = , elName, elType; // проходимся в цикле по всем элементам формы for(var i = 0; i

    На выходе, в переменной url, мы получим строку вида "http://site.com/handler.php?name1=val1&name2=val2&nameN=valN". Если на предыдущих этапах сложностей не возникло, то можно переходить непосредственно к ajax-запросу и это всё продолжаем писать в функции sendAjaxRequest . Но и тут нужно внести одну ремарку. Так как еще остаются пользователи, которые пользуются старыми версиями IE, то приходится учитывать этот момент при создании объекта XMLHttpRequest. Internet Explorer до десятой версии его не поддерживает, а имеет собственную реализацию - объект ActiveXObject. Поэтому напишем ещё одну функцию для создания своего объекта под определенные браузеры:

    Function getXhrObject(){ if(typeof XMLHttpRequest === "undefined"){ XMLHttpRequest = function() { try { return new window.ActiveXObject("Microsoft.XMLHTTP"); } catch(e) {} }; } return new XMLHttpRequest(); }

    Вы могли видеть и более "навороченные" реализации, но уверяю вас, что на сегодняшний день этого вполнене достаточно, т.к. говоря об устаревших версиях IE, я не беру в расчет седьмой и ниже. Почему восьмой "ослик" еще требует внимания? Для себя я это определил просто: сегодня еще достаточно популярна ОС Windows 7, а с ней по умолчанию идёт в комплекте IE8. Не все имеют возможность (напр., на работе) или не умеют, или не хотят обновлять до более гуманной версии и с этим приходится мириться... надеюсь. что не долго;)
    А мы продолжаем. Создаём новый объект XHR (XMLHttpRequest ), открываем соединение с помощью его метода open() , используем собятие onreadystatechange для проверки состояния выполнения запроса (readyState ) и статуса ответа сервера (status ) и отправляем запрос на сервер, используя метод send() . Когда readyState примет значение равное 4 (запрос завершен) и status значение 200 (OK), мы можем выводить или использовать для других целей ответ сервера, который будет нам доступен в свойстве responseText или responseXML , если мы в ответе получаем полноценный XML-документ.

    Var xhr = getXhrObject(); xhr.open("GET", url, true); xhr.onreadystatechange = function() { if(xhr.readyState == 4 && xhr.status == 200){ output.innerHTML = JSON.parse(xhr.responseText); } } xhr.send(null);

    Третий параметр в методе open(), указывает как будет производиться запрос: true - асинхронно, false - синхронно. В большинстве случаев, используют асинхронный запрос, то есть такой, когда страница не блокирует свою работу, в ожидании ответа сервера. Если вы заметили, то в коде выше, я использовал http-метод передачи данных "GET". Для метода "POST", надо еще добавлять заголовки, которые будут передаваться вместе с запросом на сервер, а так же делаем ещё некоторые изменения: вторым параметром (url ) в методе open(), у нас будет только путь к файлу-обработчику, а сформированную строку с данными формы, мы передаём в метод send():

    Var xhr = getXhrObject(); xhr.open("POST", url, true); xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); xhr.setRequestHeader("Content-length", params.length); xhr.setRequestHeader("Connection", "close"); xhr.onreadystatechange = function() { if(xhr.readyState == 4 && xhr.status == 200){ output.innerHTML = JSON.parse(xhr.responseText); } } xhr.send(params.join("&"));

    Вот, как бы и всё. Остаётся только собрать весь этот конструктор и привести полный листинг.

    Var d = document, myform, output; // кроссбраузерная установка обработчика событий function addEvent(elem, type, handler){ if(elem.addEventListener){ elem.addEventListener(type, handler, false); } else { elem.attachEvent("on"+type, handler); } return false; } // Универсальная функция для создания нового объекта XMLHttpRequest function getXhrObject(){ if(typeof XMLHttpRequest === "undefined"){ XMLHttpRequest = function() { try { return new window.ActiveXObject("Microsoft.XMLHTTP"); } catch(e) {} }; } return new XMLHttpRequest(); } // Функция Ajax-запроса function sendAjaxRequest(e){ var evt = e || window.event; // Отменяем стандартное действие формы по событию submit if(evt.preventDefault){ evt.preventDefault(); // для нормальных браузров } else { evt.returnValue = false; // для IE старых версий } // получаем новый XMLHttpRequest-объект var xhr = getXhrObject(); if(xhr){ // формируем данные формы var elems = myform.elements, // все элементы формы url = myform.action, // путь к обработчику params = , elName, elType; // проходимся в цикле по всем элементам формы for(var i = 0; i

    Кончено, такой количество строк кода, по сравнению с записью в $.ajax(), может отпугнуть особо ленивых, но знать, что можно спокойно обойтись без всяких библиотек - будет вам плюсом. И применять его всё же нужно, если в вашем проекте, вы больше нигде не используете js-фреймворки, т.к. подключив библиотеку, вы утяжелите страницу на килобайт 90, а написав на нативном JS - всего на 4, а если еще и минифицировать код, то всего лишь на 2Кб! Разницу ощущаете? ;)

    На этом я заканчиваю серию статей посвещенную Ajax. Будут вопросы - спрашивайте, по мере возможностей буду отвечать или дополнять новыми статьями. Успехов!

    Мы разобрали основной механизм работы метода jQuery $.ajax() . Теперь не плохо бы рассмотреть случаи из реальной практики: каким способом и откуда можно получать данные для передачи ajax-запросом.

    Получение данных из формы.

    Есть несколько способов получить данные из полей формы:

  • Выбирать каждое поле отдельно, получая его значение. Однако, это не очень удобно, когда полей много.
  • Использовать метод serialize()
  • Использовать метод serializeArray()
  • Остановимся на двух последних и не столько на том, как получать данные (тут всё просто ), а на том, как их обрабатывать на стороне сервера. Возьмем, к примеру, такую форму:

    HTML (файл index.html )

    Ф.И.О:
    Email:
    Пол: Мужской Женский
    Получать письма:
    Да
    Нет

    И напишем такой JS-код

    jQuery (файл script.js )

    $(function(){ $("#my_form").on("submit", function(e){ e.preventDefault(); var $that = $(this), fData = $that.serialize(); // сериализируем данные // ИЛИ // fData = $that.serializeArray(); $.ajax({ url: $that.attr("action"), // путь к обработчику берем из атрибута action type: $that.attr("method"), // метод передачи - берем из атрибута method data: {form_data: fData}, dataType: "json", success: function(json){ // В случае успешного завершения запроса... if(json){ $that.replaceWith(json); // заменим форму данными, полученными в ответе. } } }); }); });

    Теперь напишем обработчик таким образом, чтоб наглядно увидеть разницу между методами serialize() и serializeArray()

    PHP-обработчик (файл handler.php )


    Robert Sheckly,

    необходимо, помимо указания нового адреса файла - serverAddr ="http://zykov/data.xml", заменить в функции

    handleStateChange()

    resp=xmlHttp.responseText;

    resp=xmlHttp.responseXML.getElementsByTagName("name").firstChild.data;

    Тогда вместо сообщения

    Сервер передал: Привет, клиент!

    появится сообщение

    Сервер передал: Robert Sheckly

    Урок, в котором на примерах рассмотрим создание простых асинхронных AJAX запросов к серверу. В качестве метода передачи запросов будем использовать как метод GET, так и метод POST. На сервере обработку запросов выполним с помощью скриптов PHP.

    Что такое асинхронный запрос AJAX?

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

    При отправке асинхронного запроса, браузер (страница) не "замораживается", т.е. с ней, как и прежде, можно работать. Но тогда как узнать, когда придёт ответ с сервера. Чтобы это определить, необходимо отслеживать свойство браузера readyState (состояние готовности). Данное свойство содержит число, по значению которого можно судить о том, в какой стадии находится запрос. В следующей таблице приведены основные значения свойства readyState и соответствующие им состояния.

    Т.е. получается, что нам необходимо отследить, когда значение у свойства readyState будет равно 4. Это будет означать то, что на отправленный запрос, пришёл ответ с сервера. Остальные значения на практике используются довольно редко, и некоторые браузеры могут их не поддерживать.

    Для того чтобы определить на какой стадии находится запрос, необходимо использовать событие объекта XMLHttpRequest onreadystatechange . Данное событие происходит каждый раз, когда изменяется значение свойства readyState . Следовательно, в обработчике этого события (неименованной или именованной функции) можно прописать действия, которые будут проверять равно ли данное свойство 4 и если равно, то например, вывести ответ сервера на страницу.

    Создание асинхронного AJAX запроса (метод GET)

    Рассмотрим создание асинхронного AJAX запроса на примере, который будет после загрузки страницы приветствовать пользователя и отображать его IP-адрес.

    Для этого необходимо создать на сервере 2 файла в одном каталоге:

  • welcome.html – HTML-страница, которая будет отображаться пользователю. В этой же страницы поместим скрипт, который будет осуществлять все необходимые действия для работы AJAX на стороне клиента.
  • processing.php – PHP-файл, который будет обрабатывать запрос на стороне сервера, и формировать ответ. Начнём разработку с создания основной структуры файла welcome.html
  • Пример работы AJAX Пример работы AJAX // Здесь поместим код JavaScript, который будет отправлять запрос на сервер, получать его и обновлять содержимое страницы. Всё это будет работать без перезагрузки страницы

    Рассмотрим последовательность действий, которые необходимо выполнить на стороне клиента (в коде JavaScript):

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

    Создадим переменную, которая будет содержать экземпляр объекта XHR (XMLHttpRequest).

    Настроим запрос с помощью метода open() .

    Указываются следующие параметры:

    • Метод, с помощью которого будет посылаться запрос на сервер (GET, POST).
    • URL-адрес, который будет обрабатывать запрос на сервере.
    • Тип запроса: синхронный (false) или асинхронный (true).
    • Имя и пароль при необходимости.
  • Подпишемся на событие onreadystatechange объекта XHR и укажем обработчик в виде анонимной или именованной функции. После этого создадим код внутри этой функции, который будет проверять состояние ответа, и выполнять определённые действия на странице. Ответ, который приходит с сервера, всегда находится в свойстве responseText .

    Дополнительно с проверкой значения свойства readyState числу 4, можно проверять и значение свойства status . Данное свойство определяет статус запроса. Если оно равно 200, то всё OK . А иначе произошла ошибка (например, 404 – URL не найден).

    Отправим запрос на сервер с помощью метода send() .

    Если используем для отправки запроса метод GET, то передавать данные в параметр данного метода не надо. Они передаются в составе URL.

    Если используем для отправки запроса метод POST, то данные необходимо передать в качестве параметра методу send() . Кроме этого, перед вызовом данного метода необходимо установить заголовок Content-Type, чтобы сервер знал в какой кодировке пришёл к нему запрос и смог его расшифровать.

    Содержимое элемента script:

    // 2. Создание переменной request var request = new XMLHttpRequest(); // 3. Настройка запроса request.open("GET","processing.php",true); // 4. Подписка на событие onreadystatechange и обработка его с помощью анонимной функции request.addEventListener("readystatechange", function() { // если состояния запроса 4 и статус запроса 200 (OK) if ((request.readyState==4) && (request.status==200)) { // например, выведем объект XHR в консоль браузера console.log(request); // и ответ (текст), пришедший с сервера в окне alert console.log(request.responseText); // получить элемент c id = welcome var welcome = document.getElementById("welcome"); // заменить содержимое элемента ответом, пришедшим с сервера welcome.innerHTML = request.responseText; } }); // 5. Отправка запроса на сервер request.send();

    В итоге файл welcome.html будет иметь следующий код:

    Пример работы AJAX Пример работы AJAX window.addEventListener("load",function() { var request = new XMLHttpRequest(); request.open("GET","processing.php",true); request.addEventListener("readystatechange", function() { if ((request.readyState==4) && (request.status==200)) { var welcome = document.getElementById("welcome"); welcome.innerHTML = request.responseText; } }); request.send(); });

    На сервере (с помощью php):

  • Получим данные. Если данные посланы через метод GET , то из глобального массива $_GET["имя"] . А если данные переданы с помощью метода POST , то из глобального массива $_POST["имя"] .
  • Используя эти данные, выполним некоторые действия на сервере. В результате которых получим некоторый ответ. Выведем его с помощью echo .
  • Понравилась статья? Поделитесь ей