Прокачиваем AJAX
Статья не для начинающих ☝️🧐
У нас есть три способа для «прокачки» AJAX в jQuery: это создание префильтров, добавление новых конверторов и транспортов.
Префильтры
Префильтр – это функция, которая будет вызвана до события ajaxStart, в ней вы сможете изменить как объект jqXHR, так и любые сопутствующие настройки:
// регистрация AJAX префильтра
$.ajaxPrefilter(function( options, originalOptions, jqXHR ) {
// наши манипуляции над настройками и jqXHR
});Для чего всё это? Да вот простая задачка – не ждать «старый» AJAX-ответ, если мы запрашиваем URL заново:
// коллекция текущих запросов
var currentRequests = {};
$.ajaxPrefilter(function( options, originalOptions, jqXHR ) {
// наша произвольная настройка
if ( options.abortOnRetry ) {
if ( currentRequests[ options.url ] ) {
// отменяем старый запрос
currentRequests[ options.url ].abort();
}
currentRequests[ options.url ] = jqXHR;
}
});
// вызов с использованием фильтра
$.ajax({
/* ... */
abortOnRetry: true
})Ещё можно изменить опции вызова, вот пример, который по флагу crossDomain пересылает запрос на заранее подготовленную проксирующую страницу на нашем сервере:
Префильтры можно «вешать» на определенный тип dataType (т.е. в зависимости от ожидаемого типа данных от сервера будут срабатывать различные фильтры):
Ну и последнее: для переключения dataType на какой-нибудь другой тип нам достаточно будет вернуть необходимое значение:
Будьте очень осторожны, когда оперируете глобальными настройками, да ещё через такую неявную фичу, как фильтры. Задокументируйте подобные подходы в сопроводительной документации, иначе разработчики, которые будут в дальнейшем сопровождать ваш код, будут сильно ругаться (в качестве оных через пару месяцев можете оказаться и вы сами). И в целом настоятельно рекомендуется достаточно подробное документирование и комментирование кода. Меткая фраза, ошибочно приписываемая мэтру программирования МакКоннеллу: "Пишите код так, как будто сопровождать его будет склонный к насилию психопат, который знает, где вы живёте" (Джон Ф. Вудс).
Конверторы
Конвертор – функция обратного вызова, которая вызывается в том случае, когда полученный тип данных не совпадает с ожидаемым (т.е. dataType указан неверно).
Все конверторы хранятся в глобальных настройках ajaxSettings:
Для расширения набора конверторов потребуется метод $.ajaxSetup():
Конверторы следует использовать, если требуется внедрить произвольные форматы dataType, или для конвертации данных в нужный формат. Необходимый dataType указываем при вызове метода $.ajax():
Конверторы можно задавать также непосредственно при вызове $.ajax(), дабы не засорять общие настройки:
Чуть-чуть пояснений: мы запрашиваем «XML», который конвертируем в текст, который будет передан в наш конвертор из «
text» в «mydatatype».
Транспорт
Использование своего транспорта – это крайняя мера, прибегайте к ней только в том случае, если с поставленной задачей нельзя справиться с использованием префильтров и конверторов.
Транспорт – это объект, который предоставляет два метода send() и abort() – они будут использоваться внутри метода $.ajax(). Для регистрации своего метода транспортировки следует использовать метод $.ajaxTransport(), будет это выглядеть как-то так:
Поясню чуток параметры, с которыми будем работать:
options
настройки запроса
т.е. то, что указываем при вызове $.ajax()
originalOptions
«чистые» настройки,
даже без учёта изменений «по умолчанию»
jqXHR
объект jQuery XMLHttpRequest
headers
заголовки запроса в виде связки «ключ-значение»
completeCallback
функция обратного вызова, её следует использовать для оповещения о завершении запроса
Функция completeCallback() имеет следующую сигнатуру:
где:
status
HTTP статус ответа
statusText
текстовая интерпретация статуса ответа
responses
опционально – объект, содержащий ответы сервера во всех форматах, которые поддерживает транспорт;
например, родной XMLHttpRequest будет выглядеть как { xml: XMLData, text: textData } при запросе XML документа
headers
опционально – строка, содержащая заголовки ответа сервера, если транспорт может их получить;
например, метод XMLHttpRequest.getAllResponseHeaders() это осилит
Как и префильтры, транспорт можно привязывать к определенному типу запрашиваемых данных:
А теперь мега-напряг – добавим транспорт «image» на нашу страницу:
Теперь можно воспользоваться данным транспортом:
Я хотел бы ещё раз напомнить, что это «advanced level», и данный раздел лишний в учебнике «для начинающих».
По следам официальной документации:
Last updated