Ajax-запрос

Материал из JQuery

Перейти к: навигация, поиск
jQuery.ajax()

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

jQuery.ajax(url,[settings]):jqXHR1.5

url — адрес запроса.
settings — в этом параметре можно задать настройки для данного запроса. Задается с помощью объекта в формате {имя:значение, имя:значение...}. Ни одна из настроек не является обязательной. Установить настройки по умолчанию можно с помощью метода $.ajaxSetup().

jQuery.ajax(settings):jqXHR1.0

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

Содержание

Список настроек

↓  название :тип (значение по умолчанию)
accepts:map(зависит от DataType)
При выполнении запроса, в заголовках (header) указываются допустимые типы содержимого, ожидаемого от сервера. Значения этих типов будут взяты из параметра accepts.
async:boolean(true)
По умолчанию, все запросы без перезагрузки страницы происходят асинхронно (то есть после отправки запроса на сервер, страница не останавливает свою работу в ожидании ответа). Если вам понадобиться синхронное выполнение запроса, то установите параметр в false. Кроссдоменные запросы и запросы типа "jsonp" не могут выполняться в синхронном режиме.

Имейте ввиду, что выполнение запросов в синхронном режиме может привести к блокировке страницы, пока запрос не будет полностью выполнен.

beforeSend(jqXHR, settings):function
Это поле содержит функцию, которая будет вызвана непосредственно перед отправкой ajax-запроса на сервер. Такая функция может быть полезна для модификации jqXHR-объекта (в ранних версиях библиотеки (до 1.5), вместо jqXHR используется XMLHttpRequest). Например, можно изменить/указать нужные заголовки (headers) и.т.д. Объект-jqXHR будет передан в функцию первым аргументом. Вторым аргументом передаются настройки запроса.

beforeSend относится к ajax-событиям. Поэтому если указанная в нем функция вернет false, ajax-запрос будет отменен.

Начиная с jQuery-1.5, beforeSend вызывается независимо от типа запроса.

cache:boolean(true. Для 'script' и 'jsonp' — false)
В случае значения false браузер не будет кешировать производимый запрос. Кроме этого, это приведет к добавлению строки "_=[TIMESTAMP]" в URL.
complete(jqXHR, textStatus):function, array
функция, которая будет вызвана после завершения ajax-запроса (вызывается позднее функций-обработчиков успешного (success) или аварийного (error) завершения запроса). В функцию передаются два параметра: jqXHR (в ранних версиях библиотеки (до 1.5), вместо jqXHR используется XMLHttpRequest) и статус выполнения запроса (строковое значение:"success", "notmodified", "error", "timeout", "abort", или "parsererror").

Начиная с jQuery-1.5, в параметр complete можно передать не одну функцию, а массив функций. Все функции будут вызваны в той очередности, в которой заданы в этом массиве.

contents:map
(Эта настройка появилась в jQuery-1.5) Параметр задается объектом в формате {строка:регулярное выражение} и определяет, как jQuery будет разбирать (парсить) ответ от сервера, в зависимости от его типа.
contentType:string('application/x-www-form-urlencoded')
При отправлении запроса на сервер, данные передаются в формате, указанном в contentType. По умолчанию используется 'application/x-www-form-urlencoded', который подходит в большинстве случаев. Если указать этот параметр явно, то он будет передан серверу (даже если туда не были отправлены никакие данные). Стоит отметить, что данные всегда будут передаваться в кодировке UTF-8. Это стоит учитывать при обработке данных на стороне сервера.
context:object
Позволяет указать контекст (в смысле передаваемого в переменную this значения) для всех обработчиков, связанных с выполнением текущего запроса. По умолчанию, в context храниться объект с настройками текущего ajax-запроса.

В качестве контекста можно задать DOM-элемент, который должен каким-либо образом сигнализировать о завершении запроса:

$.ajax({ url: "test.html", context: document.body, success: function(){
  // в данном случае this будет равен document.body
  $(this).addClass("done");
}});
converters:map({"* text":window.String, "text html":true, "text json":jQuery.parseJSON, "text xml":jQuery.parseXML})
(Эта настройка появилась в jQuery-1.5) Данный параметр определяет, с помощью каких функций будет производиться конвертация значений из одного типа, в другой. Представлен объектом в формате {строка:функция}, где строка содержит названия двух типов через пробел ("конвертировать_из конвертировать_в").
crossDomain:boolean(false при запросах на тот же домен, true в случае запросах в чужую доменную зону)
(Эта настройка появилась в jQuery-1.5) Если вы хотите сделать кроссдоменный запрос в ту же доменную зону (например jsonp-запрос), установите этот параметр в true. Это позволит, к примеру, сделать перенаправление запроса на другой домен с вашего сервера.
Данные, которые будут отправлены на сервер. Если они заданы не строчным значением, то будут предварительно преобразован в строку. Избежать этого преобразования можно изменив параметр processData (его описание можно найти ниже).

В случае запроса методом GET, строка с данными добавляется в конец url. Если данные задаются с помощью объекта, то он должен соответствовать формату: {fName1:value1, fName2:value2, ...}.

dataFilter(data, type):function
Функция, которая будет осуществлять предварительную обработку данных, присланных сервером. В функцию эту передаются два параметра: упомянутые данные и значение параметра dataType. Указанная в dataFilter функция, должна возвращать обработанные данные.
dataType:string(определяется автоматически (xml, json, script, или html))
Тип данных, в котором ожидается получить ответ от сервера. Если он не задан, jQuery попытается определить его автоматически с помощью полученного от сервера MIME. Ниже можно найти подробности использования этого параметра.
error(jqXHR, textStatus, errorThrown):function,array
Функция, которая будет вызвана в случае неудачного завершения запроса к серверу. Ей предоставляются три параметра: jqXHR (в более ранних версиях библиотеки (до 1.5), вместо jqXHR используется XMLHttpRequest), строка с описанием произошедшей ошибки, а так же объект исключения, если такое произошло. Возможные значения второго аргумента: "timeout", "error", "notmodified" и "parsererror" (в непредвиденных случаях, может быть возвращено значение null). Начиная с jQuery-1.5, этот параметр может принимать как одну функцию, так и массив функций.

Событие error не определено для dataType равных script и JSONP.

error относится к ajax-событиям.

global:boolean(true)
Отвечает за работу глобальных событий ajax-запроса (подробнее в соответствующем разделе). Если задать этому параметру значение false, глобальные события для данного запроса вызываться не будут.
headers:map({})
(Эта настройка появилась в jQuery-1.5) В этом поле можно указать дополнительные заголовки запроса (header). Эти изменения будут введены до вызова beforeSend, в которой могут быть произведены окончательные правки заголовков.
ifModified:boolean(false)
При переводе этой настройки в true, запрос будет выполнен со статусом "успешно", лишь в случае, если ответ от сервера отличается от предыдущего ответом. jQuery проверяет этот факт обращаясь к заголовку Last-Modified. Начиная с jQuery-1.4, кроме Last-Modified проверяется и 'etag' (оба они предоставляются сервером и необходимы для оповещения браузера о том, что запрашиваемые данные с сервера не изменены с предыдущего запроса).
isLocal:boolean(в зависимости от текущего протокола)
(Эта настройка появилась в jQuery-1.5.1) Позволяет установить статус источника страницы локальным (как если бы это происходило по протоколу file), даже если jQuery распознал его иначе. Библиотека решает, что страница запущена локально в случае следующих протоколов: file, *-extension, и widget.

Рекомендуется устанавливать значение параметраisLocal глобально — с помощью функциии $.ajaxSetup(), а не в настройках отдельных ajax-запросов.

Определяет имя параметра, который добавляется в url при jsonp-запросе (по умолчанию, используется "callback" — "httр://siteName.ru?callback=...").

Начиная с jQuery-1.5, указав в этом параметре false, вы предотвратите добавление в url дополнительного параметра. В этом случае необходимо явно установить значение свойства jsonpCallback. Например так: {jsonp:false, jsonpCallback:"callbackName"}.

jsonpCallback:string,function
Определяет имя функции, которая будет вызвана при ответе сервера на jsonp-запрос. По умолчанию, jQuery генерирует произвольное название этой функции, что является более предпочтительным вариантом, упрощающим работу библиотеки. Один из причин, при котором стоит указывать собственную функцию обработки jsonp-запроса, является улучшение кеширования GET-запросов.

Начиная с jQuery-1.5, вы можете указать функцию в этом параметре, для того, чтобы обработать ответ сервера самостоятельно. В этом случае, указанная функция должна возвращать полученные от сервера данные (в указанной функции они будут доступны в первом параметре).

mimeType:string
(Эта настройка появилась в jQuery-1.5.1) В этом поле можно указать тип данных (в mime-формате), в котором ожидается ответ с сервера. Это приведет к замене аналогичного поля в объекте XMLHttpRequest.
password:string
Пароль для аутентификации на сервере, если это требуется.
processData:boolean(true)
По умолчанию, все передаваемые на сервер данные, предварительно преобразуются в строку (url-формата: fName1=value1&fName2=value2&...) соответствующую "application/x-www-form-urlencoded". Если вам необходимо отправить данные, которые нельзя подвергать подобной обработке (например документ-DOM), то следует отключить опцию processData.
scriptCharset:string
Этот параметр используется для кроссдоменных ajax-запросов типа GET, dataType при этом может быть или "jsonp", или "script". Определяет кодировку, в которой будет выполнен кроссдоменный запрос. Это необходимо, в случае, если сервер на чужом домене использует кодировку, отличную от кодировке на сервере родного домена.
statusCode:map({})
(Эта настройка появилась в jQuery-1.5) набор пар, в котором кодам выполнения запроса сопоставляются функции, которые при этом будет вызваны. Например, для кода 404 (страницы не существуют) можно сделать вывод сообщения на экран:
$.ajax({
  statusCode:{
    404:function(){
      alert('Страница не найдена');
    }
  }
});

Функции, реагирующие на коды удачного выполнения запроса будут получать те же аргументы, что и функции-обработчики удачного выполнения запроса (указанные в параметре success), а функции, срабатывающие на коды ошибок, будут такими же, как и у error-функций.

success(data, textStatus, jqXHR):function,array
Функция, которая будет вызвана в случае удачного завершения запроса к серверу. Ей будут переданы три параметра: данные, присланные сервером и уже прошедшие предварительную обработку (которая отлична для разных dataType). Второй параметр — строка со статусом выполнения. Третий параметр содержит объект jqXHR (в более ранних версиях библиотеки (до 1.5), вместо jqXHR используется XMLHttpRequest). Начиная с jQuery-1.5, вместо одной функции, этот параметр может принимать массив функций.

success относится к ajax-событиям

timeout:integer
Время ожидания ответа от сервера. Задается в в миллисекундах. Если это время будет превышено, запрос будет завершен с ошибкой и произойдет событие error (см. описание выше), которое будет иметь статус "timeout".

Время отсчитывается с момента вызова функции $.ajax. Может случиться так, что в этот момент будет запущено несколько других запросов и браузер отложит выполнение текущего запроса. В этом случае timeout может завершиться, хотя фактически, запрос даже еще не был запущен.

В jQuery-1.4 и младше, при завершении времени ожидания, объект XMLHttpRequest перейдет в состояние ошибки и доступ к его полям может вызвать исключение. В Firefox 3.0+ запросы типа script и JSONP не будут прерваны при превышении времени ожидания. Они будут завершены даже после того как это время истечет.

traditional:boolean(false)
Установите значение этого параметра в true, для того, чтобы использовать традиционные параметры преобразования (сериализации).
type:string("GET")
Определяет тип выполняемого запроса (GET или POST). Можно использовать также типы PUT и DELETE, но нужно помнить, что их поддерживают не все браузеры.
url:string(адрес текущей страницы)
Определяет адрес, на который будет отправлен запрос.
username:string
Имя пользователя для аутентификации на сервере, если это требуется.
xhr:function(ActiveXObject в IE, XMLHttpRequest в других браузерах)
Функция, которая предоставит объект XMLHttpRequest. По умолчанию, для браузеров IE этим объектом является ActiveXObject, а в остальных случаях это XMLHttpRequest. С помощью этого параметра вы можете внедрить собственную версию этого объекта.
xhrFields:map
(Эта настройка появилась в jQuery-1.5.1) Набор пар {имя:значене} для изменения/добавления значений соответствующих полей объекта XMLHttpRequest. Например, можно установить его свойство withCredentials в true, при выполнении кроссдоменного запроса:
$.ajax({
   url: a_cross_domain_url,
   xhrFields: {
      withCredentials:true
   }
});

В jQuery-1.5 свойство withCredentials не поддерживается нативным XMLHttpRequest и при кроссдоменном запросе это поле будет проигнорировано. Во всех следующих версиях библиотеки, это исправлено.

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

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

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

Пример простого использования. Выведем сообщение при удачном выполнении запроса:

$.ajax({
  url: 'ajax/test.html',
  success: function(){
    alert('Load was performed.');
  }
});


Начиная с jQuery-1.5, метод $.ajax() возвращает объект jqXHR, который помимо прочего реализует интерфейс deferred, что позволяет задавать дополнительные обработчики выполнения. Помимо стандартных для объекта deferred методов .done(), .fail() и .then(), с помощью которых можно устанавливать обработчики, в jqXHR реализованы .success(), .error() и .complete(). Это сделано для соответствия привычным названиям методов, с помощью которых устанавливаются обработчики выполнения ajax-запросов. Однако начиная с jQuery-1.8 эти три метода станут нежелательными для использования.

Для некоторых типов запросов, таких как jsonp или кроссдоменных GET-запросов, не предусматривается использование объектов XMLHttpRequest. В этом случае, передаваемые в обработчики XMLHttpRequest и textStatus будут содержать значение undefined.

Внутри обработчиков, переменная this будет содержать значение параметра context. В случае, если он не был задан, this будет содержать объект настроек.

Параметр dataType

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

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

Замечание 1: когда запрос отправляется на сторонний домен (что возможно только с dataType равным jsonp или script), обработчики ошибки выполнения (error), а так же глобальные события не сработают.

Замечание 2: тип данных, заданный в dataType не должен противоречить предоставляемой сервером MIME-информации. Например, xml-данные должны быть представлены сервером как text/xml или application/xml. Если это не будет выполнено, jquery попытается конвертировать полученные данные в указанный тип (подробнее об этом в разделе Converters).

Отправка данных на сервер

По умолчанию, запрос к серверу осуществляется 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 с application/x-www-form-urlencoded на более подходящий mime-тип.

Замечание: большинство браузеров не позволяют проводить ajax-запросы на ресурсы с доменами, поддоменами и протоколами, отличными от текущего. Однако, это ограничение не распространяется на запросы типа jsonp и script.

Получение данных с сервера

Полученные от сервера данные, могут быть предоставлены в виде строки или объекта, в зависимости от значения параметра dataType (см. пункт dataType выше). Эти данные всегда доступны в первом параметре обработчика выполнения ajax-запроса:

$.ajax({
  url: "some.php",
  success: function(data){
    alert( "Прибыли данные: " + data );
  }
});

Для типов text и xml, присланные сервером данные будут доступны так же и в jqXHR, а именно в его полях responseText или responseXML соответственно.

Продвинутые настройки

Используя параметр global можно отключать выполнение обработчиков событий (.ajaxSend(), .ajaxError() и др.) для отдельных запросов. Это может быть полезно, например в случае, если в этих обработчиках запускается/останавливается анимация загрузки. Тогда если некоторые запросы выполняются очень часто и быстро, то для них полезно будет отключить выполнение обработчиков. Для кроссдоменных script и jsonp запросов параметр global отключается автоматически.

Если для совершения запроса к серверу необходимы данные аутентификации (логин/пароль), то их можно указать в настройках username и password ajax-запроса.

На выполнение запроса к серверу отводится определенное время. Если в течении этого времени сервер не присылает ответ, то запрос завершается с ошибкой (статус "timeout"). Время ожидания ответа от сервера можно изменить, задав необходимое значение (в миллисекундах) в настройке timeout.

Может так случиться, что кодировка хоста отличается от кодировки запрашиваемого в ajax-запросе javascript файла. В таких случаях необходимо указать кодировку последнего в настройке scriptCharset.

В большинстве случаев, ajax-запрос происходит асинхронно, однако в некоторых случаях может понадобиться последовательное выполнение запроса (когда дальнейшее выполнение скрипта невозможно, без получения ответа от сервера). Сделать запрос синхронным можно если отключить настройку async. Однако стоит помнить, что в таком случае станица будет "подвисать" при ожидании ответа от сервера.

Примеры использования

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

$.ajax();
// на сервер будет отправлен GET-запрос на url-адрес текущей страницы и без указания каких-либо параметров.

Если нужно подгрузить и выполнить js-файл, то это можно сделать следующим образом:

$.ajax({
  type: "GET",
  url: "test.js",
  dataType: "script"
});

Сделаем POST-запрос на сервер, указав при этом два параметра и оповестим пользователя о удачно завершенном запросе:

$.ajax({
  type: "POST",
  url: "some.php",
  data: "name=John&location=Boston",
  success: function(msg){
    alert( "Прибыли данные: " + msg );
  }
});

Обновим содержимое нужной html-страницы:

$.ajax({
  url: "test.html",
  cache: false,
  success: function(html){
    $("#results").append(html);
  }
});

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

// присланные от сервера данные, запишем в переменную html
var html = $.ajax({
  url: "some.php",
  async: false
 }).responseText;

В качестве параметра, отправим на сервер xml-объект. Для его корректной передачи необходимо отменить предварительное преобразование параметров (processData:false). В качестве обработчика удачного завершения запроса укажем пользовательскую функцию handleResponse:

var xmlDocument = [create xml document];
 $.ajax({
   url: "page.php",
   processData: false,
   data: xmlDocument,
   success: handleResponse
 });

Расширенный подход

Начиная с jQuery-1.5 появились три новых направления, позволяющие использовать $.ajax() еще более глубоко. Первый из них (Prefilters) позволяет провести дополнительные манипуляции, непосредственно перед отправкой запроса. С помощью второго подхода (Converters) можно указать jQuery, как следует конвертировать полученные от сервера данные, если они не соответствуют ожидаемому формату. Третий подход (Transports) является наиболее низкоуровневым, он позволяет самостоятельно организовать запрос к серверу.

Prefilters

Этот подход состоит в установке обработчика, вызываемого перед выполнением каждого ajax-запроса. Этот обработчик предшествует выполнению любых других обработчиков ajax. Устанавливается он с помощью функции $.ajaxPrefilter():

$.ajaxPrefilter(function(options, originalOptions, jqXHR){
  // Изменяем настройки (options), проверяем базовые настройки (originalOptions) и объект jqXHR
});

Где
options — настройки текущего запроса,
originalOptions — настройки по умолчанию,
jqXHRjqXHR-объект данного запроса.

В Prefilters удобно обрабатывать пользовательские настройки (т.е. новые, неизвестные библиотеке настройки, указанные в запросе). Например, можно ввести собственную настройку abortOnRetry, при включении которой незавершенные запросы будут сбрасываться, в случае, если на этот-же url поступает следующий запрос:

var currentRequests = {};
 
$.ajaxPrefilter(function(options, originalOptions, jqXHR){
  if(options.abortOnRetry){
    if(currentRequests[options.url]){
      currentRequests[options.url].abort();
    }
    currentRequests[options.url] = jqXHR;
  }
});

В ajaxPrefilter удобно обрабатывать и существующие настройки. Например так можно изменить кросс-доменный запрос на перенаправленный через сервер своего домена:

$.ajaxPrefilter(function(options){
  if(options.crossDomain){
    options.url = "http://mydomain.net/proxy/" + encodeURIComponent( options.url );
    options.crossDomain = false;
  }
});

Кроме этого, можно указывать значения dataType на которых сработает prefilter. Так, к примеру, можно указать типы json и script:

$.ajaxPrefilter( "json script", function(options, originalOptions, jqXHR){
  // Изменяем настройки (options), проверяем базовые настройки (originalOptions) и объект jqXHR
});

И наконец, можно изменить значение dataType, вернув необходимое значение:

$.ajaxPrefilter(function(options){
  // изменим dataType на script, если url соответствует определенным условиям
  if (isActuallyScript(options.url)){
    return "script";
  }
});

Такой подход гарантирует не только то, что запрос изменит свой тип на script, но и то, что остальные prefilter-обработчики с указанием этого типа в первом параметре, будут также выполнены.

Converters

Этот принцип заключается в установке обработчика, который сработает, если указанный в настройках dataType не совпадет с типом данных, присланных сервером.

Converters является настройкой ajax, поэтому может быть задан глобально:

// так можно задать обработчик, который сработает, если вместо
// указанного вами в dataType типа mydatatype придут данные типа text
$.ajaxSetup({
  converters:{
    "text mydatatype":function( textValue ){
      if(valid( textValue )){
        // обработка переданного текста
        return mydatatypeValue;
      } else {
        // если присланные сервером данные совсем не соответствуют ожидаемым,
        // можно вызвать исключение.
        throw exceptionObject;
      }
    }
  }
});

Converters поможет при введении собственного (пользовательского) dataType. Важно отметить, что в названии такого dataType должны использоваться только строчные буквы! Запрос данных, упомянутого выше типа "mydatatype", мог бы выглядеть следующим образом:

$.ajax( url,{
  dataType:"mydatatype"
});

Converters может быть задан и не глобально (т.е. для конкретного запроса). В следующем примере, будет продемонстрирован запрос к серверу, ответ от которого должен будет прийти в xml, после чего конвертирован в обычный текст (способ конвертации будет задан нами в параметре converters и будет действовать только для этого запроса), а из текста в "mydatatype" (используя заданный глобально converters):

$.ajax( url, {
  dataType: "xml text mydatatype",
  converters: {
    "xml text": function( xmlValue ) {
      // здесь будут вытащены нужные текстовые данные из предоставленного xml
      return textValue;
    }
  }
});