Jquery синхронный ajax. JavaScript - Асинхронные AJAX запросы на примерах. Методы объекта XMLHttpRequest

Урок, в котором на примерах рассмотрим создание простых асинхронных 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 .
  • Пункт 1 Пункт 2 Пункт 3 Пункт 4 Пункт 5 XML;

    Пример 5

    Используем данные JSON. Входные параметры можно использовать в качестве атрибутов получаемого объекта.

    $.ajax({ dataType: "json", url: "response.php?action=sample5", success: function(jsondata){ $(".results").html("Name = " + jsondata.name + ", Nickname = " + jsondata.nickname); } });

    Сервер должен возвращать данные в формате JSON:

    $aRes = array("name" => "Andrew", "nickname" => "Aramis"); require_once("Services_JSON.php"); $oJson = new Services_JSON(); echo $oJson->encode($aRes);

    jQuery.ajax() — осуществляет запрос к серверу без перезагрузки страницы. Это низкоуровневый метод, обладающий большим количеством настроек. Он лежит в основе работы всех ajax, которые, зачастую, легче понять и использовать, но которые все же предоставляют ограниченную функциональность по сравнению с данным методом.

    $.ajax() возвращает объект XMLHttpRequest. В большинстве случаев Вам не понадобится работать непосредственно с этим объектом, но он все же доступен, в случае, если Вам необходимо прервать запрос вручную.

    В качестве аргумента функции $.ajax() передается объект, состоящий из пар ключ/значение, которые используются для инициализации и управления запросом.

    Ajax-запрос имеет два варианта использования:

    jQuery.ajax(url [, settings ])

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

    Список настроек (settings)
  • accepts (по умолчанию: зависит от DataType)
    Тип: объект.
    При выполнении запроса, в заголовках (header) указываются допустимые типы содержимого, ожидаемого от сервера. Значения этих типов будут взяты из параметра accepts. Например, в следующем примере указываются допустимые типы customtype:

    $.ajax({ accepts: { mycustomtype: "application/x-some-custom-type" }, converters: { "text mycustomtype": function(result) { return newresult; } }, dataType: "mycustomtype" });

    $ . ajax ({

    accepts : {

    mycustomtype : "application/x-some-custom-type"

    converters : {

    "text mycustomtype" : function (result ) {

    return newresult ;

    dataType : "mycustomtype"

    } ) ;

  • async (по умолчанию: true)
    Тип: логическое значение.
    По умолчанию, все запросы отсылаются асинхронно (то есть после отправки запроса на сервер, страница не останавливает свою работу в ожидании ответа). Если Вам необходимо посылать запросы синхронно, установите данную опцию в false. Кроссдоменные запросы и запросы типа «jsonp» не могут выполняться в синхронном режиме. Обратите внимание, что синхронные запросы могут на время выполнения запроса заблокировать браузер.
  • beforeSend(jqXHR, settings)
    Тип: функция.
    Содержит функцию, которая будет вызвана непосредственно перед отправкой ajax-запроса на сервер. Такая функция может быть полезна для модификации jqXHR-объекта (в ранних версиях библиотеки (до 1.5), вместо jqXHR используется XMLHttpRequest). Например, можно изменить/указать нужные заголовки (headers) и.т.д. Объект-jqXHR будет передан в функцию первым аргументом. Вторым аргументом передаются настройки запроса.
    beforeSend относится к ajax-событиям. Поэтому если указанная в нем функция вернет false, ajax-запрос будет отменен.Начиная с jQuery-1.5, beforeSend вызывается независимо от типа запроса.
  • cache (по умолчанию: true, false для dataType "script" и "jsonp")
    Тип: логическое значение.
    если вы хотите, чтобы браузер не кэшировал производимый запрос, то установите этот параметр в false. Обратите внимание, что если параметр установлен в false, то в URL будет добавлена строка «_=».
  • complete(jqXHR, textStatus)
    Тип: функция.
    Функция, которая исполняется всякий раз после завершения запроса AJAX (после того, как выполнились success и error). В функцию передаются два параметра: jqXHR (в ранних версиях библиотеки (до 1.5), вместо jqXHR используется XMLHttpRequest) и статус выполнения запроса (строковое значение:»success», «notmodified», «error», «timeout», «abort», или «parsererror»).
    Начиная с jQuery-1.5, в параметр complete можно передать не одну функцию, а массив функций. Все функции будут вызваны в той очередности, в которой заданы в этом массиве.
  • contents
    Тип: объект.
    Параметр появился в jQuery-1.5 Задается объектом в формате {строка:регулярное выражение} и определяет, как jQuery будет разбирать (парсить) ответ от сервера, в зависимости от его типа.
  • contentType
    Тип: логическое значение или строка.
    При отправлении запроса на сервер, данные передаются в формате, указанном в contentType. По умолчанию используется ‘application/x-www-form-urlencoded; charset=UTF-8’, который подходит в большинстве случаев. Если указать этот параметр явно, то он будет передан серверу (даже если туда не были отправлены никакие данные).
    С jQuery-1.6 можно передавать false чтобы не устанавливать заголовок.
  • context
    Тип: объект.
    Объект, который станет контекстом после выполнения запроса (передаваемое значение в переменную this). Например, если указать в качестве контекста DOM-элемент, то все обработчики ajax-запроса тоже будут выполняться в контексте данного DOM-элемента. В данном примере ключевое слово this будет содержать document.body:

    $.ajax({ url: "test.html", context: document.body }).done(function() { $(this).addClass("done"); });

    $ . ajax ({

    url : "test.html" ,

    context : document . body

    } ) . done (function () {

    $ (this ) . addClass ("done" ) ;

    } ) ;

  • converters (по умолчанию: {"* text": window.String, "text html": true, "text json": jQuery.parseJSON, "text xml": jQuery.parseXML})
    Тип: объект.
    Параметр появился в jQuery-1.5 Определяет, с помощью каких функций будет производиться конвертация значений из одного типа, в другой.
  • crossDomain (по умолчанию: false для одного и того же домена, true для кроссдоменных запросов)
    Тип: логическое значение.
    Параметр появился в jQuery-1.5 Если вы хотите, чтобы выполнить кросс-доменный запрос (например, JSONP) на том же домене, выставите true в настройке crossDomain. Это позволяет, например, сделать серверные перенаправление на другой домен.
  • data
    Тип: объект, строка или массив.
    Данные, которые будут переданы на сервер. Если данные не являются строкой, то они конвертируются в строку запроса. Для запросов типа GET данные прикрепляются к URL. Объект должен состоять из пар ключ/значение. Если в значении массив, то jQuery упорядочивает значения в зависимости от настройки traditional. По умолчанию, например, {foo:["bar1", "bar2"]} превращается в &foo=bar1&foo=bar2 .
  • dataFilter (data, type)
    Тип: функция.
    Функция, которая будет осуществлять предварительную обработку данных, присланных сервером, т.е. она должна играть роль фильтра и возвращать очищенную строку. В эту функцию передаются два параметра: упомянутые данные и значение параметра dataType . Указанная в dataFilter функция, должна возвращать обработанные данные.
  • dataType (по умолчанию: определяется автоматически (xml, json, script, или html))
    Тип: строка.
    Тип данных, в котором ожидается получить ответ от сервера. Если он не задан, jQuery попытается определить его автоматически с помощью полученного от сервера MIME.
  • error
    Тип: функция
    Функция, которая будет вызвана в случае неудачного завершения запроса к серверу. Ей предоставляются три параметра: jqXHR (до 1.5 используется XMLHttpRequest), строка с описанием произошедшей ошибки, а так же объект исключения, если такое произошло. Возможные значения второго аргумента: «timeout», «error», «notmodified» и «parsererror» (в непредвиденных случаях, может быть возвращено значение null). Начиная с jQuery-1.5, этот параметр может принимать как одну функцию, так и массив функций.
    Событие error не происходит при dataType равному script или JSONP.
  • global (по умолчанию: true)
    Тип: логическое значение.
    Отвечает за работу глобальных событий ajax-запроса (например ajaxStart или ajaxStop). Если задать этому параметру значение false , глобальные события для данного запроса вызываться не будут.
  • headers
    Тип: объект.
    Параметр появился в jQuery-1.5 Здесь можно указать дополнительные заголовки запроса (header). Значения этой настройки будут введены до вызова функции beforeSend, в которой могут быть внесены окончательные изменения в заголовки.
  • ifModified
    Тип: логическое значение.
    При переводе этой настройки в true , запрос будет выполнен со статусом «успешно», лишь в случае, если ответ от сервера отличается от предыдущего ответом. jQuery проверяет этот факт обращаясь к заголовку Last-Modified. Начиная с jQuery-1.4, кроме Last-Modified проверяется и ‘etag’ (оба они предоставляются сервером и необходимы для оповещения браузера о том, что запрашиваемые данные с сервера не изменены с предыдущего запроса).
  • isLocal
    Тип: логическое значение.
    Параметр появился в jQuery-1.5.1 Позволяет установить статус источника страницы локальным (как если бы это происходило по протоколу file), даже если jQuery распознал его иначе. Библиотека решает, что страница запущена локально в случае следующих протоколов: file, *-extension, и widget .Рекомендуется устанавливать значение параметра isLocal глобально - с помощью функциии $.ajaxSetup() , а не в настройках отдельных ajax-запросов.
  • jsonp
    Тип: строка или логическое значение.
    Определяет имя параметра, который добавляется в url JSONP-запроса (по умолчанию, используется «callback»). К примеру настройка {jsonp:"onJSONPLoad"} преобразуется в часть url строки "onJSONPLoad=?" . Начиная с версии 1.5, указание в этом параметре false предотвращает добавление в url дополнительного параметра. В этом случае, необходимо установить значение настройки jsonpCallback. Например так: {jsonp:false, jsonpCallback:"callbackName"} .
  • jsonpCallback
    Тип: строка или функция.
    Определяет имя функции, которая будет вызвана при ответе сервера на jsonp-запрос. По умолчанию, jQuery генерирует произвольное название этой функции, что является более предпочтительным вариантом, упрощающим работу библиотеки. Один из причин, при котором стоит указывать собственную функцию обработки jsonp-запроса, является улучшение кеширования GET-запросов.
    Начиная с jQuery-1.5, вы можете указать функцию в этом параметре, для того, чтобы обработать ответ сервера самостоятельно. В этом случае, указанная функция должна возвращать полученные от сервера данные (в указанной функции они будут доступны в первом параметре).
  • method (по умолчанию: "GET")
    Тип: строка.
    Параметр появился в jQuery-1.9.0 Позволяет указать тип запроса к серверу ("POST" , "GET" , "PUT")
  • mimeType
    Тип: строка.
    Параметр появился в jQuery-1.5.1 В этом поле можно указать тип данных, в котором ожидается ответ от сервера вместо XHR
  • password
    Тип: строка.
    Пароль для аутентификации на сервере, если это требуется.
  • processData (по умолчанию true)
    Тип: логическое значение.
    По умолчанию передаваемые на сервер данные преобразуются из объекта в строку запроса (url-формата: fName1=value1&fName2=value2&...) и отправляются как "application/x-www-form-urlencoded" . Если вам необходимо отправить DOM-документ или иные данные, которые нельзя подвергать конвертированию установите опцию processData в false .
  • scriptCharset
    Тип: строка.
    Применяется только для Ajax GET-запросов, dataType при этом может быть или «jsonp», или «script». Если сервер на стороннем домене использует кодировку, отличную от вашей, необходимо указать кодировку стороннего сервера.
  • statusCode
    Тип: объект.
    Параметр появился в jQuery-1.5.0 Набор пар, в котором кодам выполнения запроса сопоставляются функции, которые при этом будет вызваны. Например, для кода 404 (страницы не существуют) можно сделать вывод сообщения на экран:

    $.ajax({ statusCode: { 404: function() { alert("page not found"); } } });

    $ . ajax ({

    statusCode : {

    404 : function () {

    alert ("page not found" ) ;

    } ) ;


    Если запрос прошёл успешно, то в качестве параметра, анонимная функция будет принимать те же параметры, что функции-обработчики удачного выполнения запроса (указанные в параметре success), а при ошибке такие же, как и у error-функций.
  • success (data, textStatus, jqXHR)
    Тип: функция, массив.
    Функция, которая будет вызвана в случае успешного завершения запроса к серверу. Принимает 3 аргумента:
    • данные (data), присланные сервером и прошедшие предварительную обработку;
    • строка со статусом выполнения (textStatus);
    • объект jqXHR (в версиях до 1.5 вместо jqXHR используется XMLHttpRequest). С версии jQuery 1.5, вместо одной функции, этот параметр может принимать массив функций.
  • timeout
    Тип: число.
    Время ожидания ответа от сервера в миллисекундах. Переписывает глобальную настройку этого же параметра в $.ajaxSetup(). Если это время будет превышено, запрос будет завершен с ошибкой и произойдет событие error, которое будет иметь статус «timeout».
    Время отсчитывается с момента вызова функции $.ajax. Может случиться так, что в этот момент будет запущено несколько других запросов и браузер отложит выполнение текущего запроса. В этом случае timeout может завершиться, хотя фактически, запрос даже еще не был запущен.
    В jQuery-1.4 и младше, при завершении времени ожидания, объект XMLHttpRequest перейдет в состояние ошибки и доступ к его полям может вызвать исключение. В Firefox 3.0+ запросы типа script и JSONP не будут прерваны при превышении времени ожидания. Они будут завершены даже после того как это время истечет.
  • traditional
    Тип: логическое значение.
    Установите значение этого параметра в true, для того, чтобы использовать традиционные параметры преобразования (сериализации).
  • type (по умолчанию: "GET")
    Тип: строка.
    Аналог параметру method . Параметр используется в jQuery младше 1.9.0
  • url (по умолчанию: адрес текущей страницы )
    Тип: строка.
    Определяет адрес, на который будет отправлен запрос.
  • username
    Тип: строка.
    Имя пользователя для аутентификации на сервере, если это требуется.
  • xhr (по умолчанию: ActiveXObject в IE, the XMLHttpRequest в других браузерах)
    Тип: функция.
    Функция, которая предоставит объект XMLHttpRequest. По умолчанию, для браузеров IE этим объектом является ActiveXObject, а в остальных случаях это XMLHttpRequest. С помощью этого параметра вы можете внедрить собственную версию этого объекта.
  • xhrFields
    Тип: объект.
    Параметр появился в jQuery-1.5.1 Набор пар {имя: значене} для изменения/добавления значений соответствующих полей объектаXMLHttpRequest. Например, можно установить его свойство withCredentials в true , при выполнении кроссдоменного запроса:

    $.ajax({ url: a_cross_domain_url, xhrFields: { withCredentials: true } });

    $ . ajax ({

    url : a_cross_domain_url ,

    xhrFields : {

    withCredentials : true

    } ) ;

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

    Наиболее простым вариантом использования будет вызов $.ajax() без задания параметров:

    $ . ajax () ;

    Обработчики событий

    Настройки beforeSend, error, dataFilter, success and complete позволяют установить обработчики событий, которые происходят в определенные моменты выполнения каждого ajax-запроса.

    • beforeSend происходит непосредственно перед отправкой запроса на сервер;
    • error происходит в случае неудачного выполнения запроса;
    • dataFilter происходит в момент прибытия данных с сервера. Позволяет обработать «сырые» данные, присланные сервером;
    • success происходит в случае удачного завершения запроса;
    • complete происходит в случае любого завершения запроса.
    • success : function () {

      alert ("Данные успешно отправлены." ) ;

      } ) ;

      Внимание! Рассмотренные выше настройки.success(), .error() и.complete() были добавлены в jQuery-1.5 помимо стандартных для объекта deferred методов.done(), .fail() и.then(), с помощью которых можно устанавливать обработчики, однако начиная с jQuery-1.8 эти три метода станут нежелательными для использования.

      Параметр dataType

      Функция $.ajax() узнает о типе присланных сервером данных от самого сервера (средствами MIME). Кроме этого, существует возможность лично указать (уточнить), как следует интерпретировать эти данные. Это делается с помощью параметра dataType . Возможные значения этого параметра:

      • «xml» - полученный xml-документ будет доступен в текстовом виде. С ним можно работать стандартными средствами jQuery (также как и с документом html).
      • «html» - полученный html будет доступен в текстовом виде. Если он содержит скрипты в тегах , то они будут автоматически выполнены, только когда html-текст будет помещен в DOM.
      • «script» - полученные данные будут исполнены как javascript. Переменные, которые обычно содержат ответ от сервера будут содержать объект jqXHR.
      • «json», «jsonp» - полученные данные будут предварительно преобразованы в javascript-объект. Если разбор окажется неудачным (что может случиться, если json содержит ошибки), то будет вызвано исключение ошибки разбора файла. Если сервер, к которому вы обращаетесь, находится на другом домене, то вместо json следует использовать jsonp.
      • «text» - полученные данные окажутся доступными в виде обычного текста, без предварительной обработки.
      Отправка данных на сервер

      По умолчанию, запрос к серверу осуществляется HTTP-методом GET. При необходимости сделать запрос методом POST, нужно указать соответствующее значение в настройке type . Данные, отправляемые методом POST будут преобразованы в UTF-8, если они находятся в другой кодировке, как того требует стандарт W3C XMLHTTPRequest.

      Параметр data может быть задан либо строкой в формате key1=value1&key2=value2 (формат передачи данных в url), либо объектом с набором пар {имя:значение} - {key1: "value1", key2: "value2"} . В последнем случае, перед отправкой данных jQuery преобразует заданный объект в строку, с помощью $.param(). Однако, это преобразование можно отменить, указав в настройке processData значение false. Преобразование в строку нежелательно, например, в случае отправки на сервер xml-объекта. В этом случае, желательно изменить настройку contentType

      url : "test.php" ,

      success : function (data ) {

      alert ("Получены данные: " + data ) ;

      } ) ;