Основы AJAX для начинающих. Пример использования метода $.get()

Мы познакомились с прямыми методами jQuery для работы с Ajax (такими как get(), post() и load()). В этой статье описан низкоуровневый программный интерфейс jQuery Ajax API .

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

Простые Ajax-запросы

Создавать запросы с помощью низкоуровневого API не намного сложнее, чем с помощью прямых или вспомогательных методов. Разница состоит в том, что такой подход позволяет контролировать многие другие аспекты запроса и получать о выполняющемся запросе гораздо больше информации. Центральное место в низкоуровневом API занимает метод ajax() , простой пример использования которого приведен ниже (здесь используется исходный файл и файл mydata.json, описанные в предыдущей статье):

$(function() { $.ajax("mydata.json", { success: function(data) { var template = $("#flowerTmpl"); template.tmpl(data.slice(0, 3)).appendTo("#row1"); template.tmpl(data.slice(3)).appendTo("#row2"); } }); });

Аргументами метода ajax() являются запрашиваемый URL и объект отображения данных, свойства которого определяют набор пар "ключ-значение", каждая из которых определяет некий параметр запроса. Здесь передаваемый методу ajax() объект содержит только один параметр, success, задающий функцию, которая будет вызываться в случае успешного выполнения запроса.

В данном примере мы запрашиваем у сервера файл mydata.json и используем его вместе с шаблоном данных для создания элементов и вставки их в документ, как это делалось в предыдущей статье с помощью прямых методов. По умолчанию метод ajax() создает HTTP-запрос GET, т.е. данный пример эквивалентен использованию методов get() и getJSON().

Объект jqXHR

Метод ajax() возвращает объект jqXHR, который можно использовать для получения подробной информации о запросе и с которым можно взаимодействовать. Объект jqXHR представляет собой оболочку объекта XMLHttpRequest , составляющую фундамент браузерной поддержки Ajax.

При выполнении большинства операций Ajax объект jqXHR можно просто игнорировать, что я и рекомендую делать. Этот объект используется в тех случаях, когда необходимо получить более полную информацию об ответе сервера, чем та, которую удается получить иными способами. Кроме того, его можно использовать для настройки параметров Ajax-запроса, но это проще сделать, используя настройки, доступные для метода ajax(). Свойства и методы объекта jqXHR описаны в таблице ниже:

Свойства и методы объекта jqXHR Свойство/метод Описание
readyState Возвращает индикатор хода выполнения запроса на протяжении всего его жизненного цикла, принимающий значения от 0 (запрос не отправлен) до 4 (запрос завершен)
status Возвращает код состояния HTTP, отправленный сервером
statusText Возвращает текстовое описание кода состояния
responseXML Возвращает ответ в виде XML (если он является XML-документом)
responseText Возвращает ответ в виде строки
setRequest(имя, значение) Возвращает заголовок запроса (это можно сделать проще с помощью параметра headers)
getAllResponseHeaders() Возвращает в виде строки все заголовки, содержащиеся в ответе
getResponseHeaders(имя) Возвращает значение указанного заголовка ответа
abort() Прерывает запрос

Объект jqXHR встречается в нескольких местах кода. Сначала он используется для сохранения результата, возвращаемого методом ajax(), как показано в примере ниже:

$(function() { var jqxhr = $.ajax("mydata.json", { success: function(data) { var template = $("#flowerTmpl"); template.tmpl(data.slice(0, 3)).appendTo("#row1"); template.tmpl(data.slice(3)).appendTo("#row2"); } }); var timerID = setInterval(function() { console.log("Статус: " + jqxhr.status + " " + jqxhr.statusText); if (jqxhr.readyState == 4) { console.log("Запрос выполнен: " + jqxhr.responseText); clearInterval(timerID); } }, 100); });

В этом примере мы сохраняем результат, возвращаемый методом ajax(), а затем используем метод setInterval() для вывода информации о запросе каждые 100 мс. Использование результата, возвращаемого методом ajax(), не изменяет того факта, что запрос выполняется асинхронно, поэтому при работе с объектом jqXHR необходимо соблюдать меры предосторожности. Для проверки состояния запроса мы используем свойство readyState (завершению запроса соответствует значение 4) и выводим ответ сервера на консоль.

Для данного сценария консольный вывод выглядит так (в вашем браузере он может выглядеть несколько иначе):

Я использую объект jqXHR лишь в редких случаях и не делаю этого вообще, если он представляет собой результат, возвращаемый методом ajax(). Библиотека jQuery автоматически запускает Ajax-запрос при вызове метода ajax(), и поэтому я не считаю возможность настройки параметров запроса сколько-нибудь полезной. Если я хочу работать с объектом jqXHR (как правило, для получения дополнительной информации об ответе сервера), то обычно делаю это через параметры обработчика событий, о которых мы поговорим далее. Они предоставляют мне информацию о состоянии запроса, что избавляет от необходимости выяснять его.

Задание URL-адреса запроса

Одним из наиболее важных доступных параметров является параметр url , позволяющий указать URL-адрес для запроса. Можно использовать этот параметр как альтернативу передаче URL-адреса в качестве аргумента метода ajax(), как показано в примере ниже:

$(function() { $.ajax({ url: "mydata.json", success: function(data) { var template = $("#flowerTmpl"); template.tmpl(data.slice(0, 3)).appendTo("#row1"); template.tmpl(data.slice(3)).appendTo("#row2"); } }); });

Создание POST-запроса

Для задания требуемого типа запроса, который необходимо выполнить, используется параметр type . По умолчанию выполняются GET-запросы, как в предыдущем примере. Пример использования метода ajax() для создания POST-запроса и отправки данных формы на сервер приведен ниже:

$(function() { $.ajax({ url: "mydata.json", success: function(data) { var template = $("#flowerTmpl"); template.tmpl(data.slice(0, 3)).appendTo("#row1"); template.tmpl(data.slice(3)).appendTo("#row2"); } }); // Обработчик клика по кнопке "Заказать" $("button").click(function(e) { $.ajax({ url: "phphandler.php", type: "post", data: $("form").serialize(), success: processServerResponse, dataType: "json" }); e.preventDefault() }); function processServerResponse(data) { // Изначально скрываем всю продукцию var inputElems = $("div.dcell").hide(); for (var prop in data) { // Отображаем только ту продукцию, заказ которой больше 0 // (в ответе от сервера содержится только такая продукция) var filtered = inputElems.has("input") .appendTo("#row1").show(); } // Скрываем базовые элементы формы $("#buttonDiv, #totalDiv").remove(); // Отображаем новые элементы из шаблона totalTmpl $("#totalTmpl").tmpl(data).appendTo("body"); } }); Всего заказов: ${total} Заказать .png"/> ${name}:

Здесь я не буду подробно описывать этот пример, т.к. мы его рассмотрели подробно в предыдущей статье (только с использованием метода post()). Отмечу только, что здесь дополнительно к type мы использовали еще несколько параметров. Для указания цели POST-запроса используется описанный ранее параметр url. Пересылаемые данные указываются с помощью параметра data, значение которого устанавливается с помощью метода serialize(), описанного в предыдущей статье. Тип данных, получаемых от сервера указывается в параметре dataType.

Работа с событиями Ajax

Несколько параметров позволяют указывать функции для обработки событий, которые могут запускаться на протяжении жизненного цикла Ajax-запроса. Именно таким способом вы будете указывать функции обратного вызова, играющие столь важную роль в Ajax-запросах. С одной из них вы уже познакомились при рассмотрении параметра success в предыдущем примере. Список параметров, связанных с событиями, вместе с их краткими описаниями приведен в таблице ниже:

Обработка успешных запросов

В примерах выше, при использовании параметра success, в вызове функции были опущены два аргумента - сообщение, описывающее результат запроса, и объект jqXHR. Пример использования функции, которая принимает эти аргументы, приведен ниже:

$(function() { $.ajax({ url: "mydata.json", success: function(data, status, jqxhr ) { console.log("Статус: " + status); console.log("jqXHR статус: " + jqxhr.status + " " + jqxhr.statusText); console.log(jqxhr.getAllResponseHeaders()); var template = $("#flowerTmpl"); template.tmpl(data.slice(0, 3)).appendTo("#row1"); template.tmpl(data.slice(3)).appendTo("#row2"); } }); });

Аргумент status - это строка, описывающая исход запроса. Функция обратного вызова, которую мы задаем, используя параметр success, выполняется лишь для успешных запросов, и поэтому значением данного аргумента обычно является success. Исключением является случай, когда вы используете параметр ifModified, описанный далее.

Функции обратного вызова для всех событий Ajax следуют одному и тому же образцу, но наибольшую пользу этот аргумент приносит в случае ряда других событий.

Последний аргумент - это объект jqXHR. Вы не должны выяснять состояние запроса, прежде чем начать работу с этим объектом, поскольку знаете, что функция выполняется лишь тогда, когда запрос завершается успешно. В этом примере объект jqXHR используется для получения информации о состоянии запроса и заголовках, которые сервер включил в ответ, а также для вывода этой информации на консоль.

В данном случае результат имеет следующий вид (в зависимости от того, какой сервер вы используете, у вас может быть другой набор заголовков):

Обработка ошибок

Параметр error используется для указания функции, которая должна вызываться при неудачном завершении запроса. Соответствующий пример приведен ниже:

Error {color: red; border: medium solid red; padding: 4px; margin: auto; width: 200px; text-align: center}

$(function() { $.ajax({ url: "NoSuchFile.json", success: function(data) { var template = $("#flowerTmpl"); template.tmpl(data.slice(0, 3)).appendTo("#row1"); template.tmpl(data.slice(3)).appendTo("#row2"); }, error: function(jqxhr, status, errorMsg) { $("") .text("Статус: " + status + " Ошибка: " + errorMsg) .insertAfter("h1"); } }); });

Здесь запрашивается отсутствующий на сервере файл NoSuchFile.json, и поэтому запрос заведомо не сможет быть выполнен, в результате чего будет вызвана функция, заданная с помощью параметра error. Аргументами этой функции являются объект jqXHR, а также сообщение о состоянии ошибки и сообщение об ошибке, полученное в ответе сервера. Внутри этой функции в документ добавляется элемент div, отображающий значения аргументов status и errorMsg, как показано на рисунке:

Настройка параметров запросов перед их отправкой

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

$(function() { $.ajax({ success: function(data) { var template = $("#flowerTmpl"); template.tmpl(data.slice(0, 3)).appendTo("#row1"); template.tmpl(data.slice(3)).appendTo("#row2"); }, error: function(jqxhr, status, errorMsg) { $("") .text("Статус: " + status + " Ошибка: " + errorMsg) .insertAfter("h1"); }, beforeSend: function(jqxhr, settings) { settings.url = "mydata.json"; } }); });

Аргументами указанной функции являются объект jqXHR (который может пригодиться для настройки заголовков запроса или отмены запроса, прежде чем он будет отправлен) и объект, содержащий параметры, переданные методу ajax(). В данном примере URL-адрес для Ajax-запроса задается с помощью параметра beforeSend.

Задание нескольких обработчиков событий

В предыдущих примерах мы реагировали на наступление событий, связанных с Ajax-запросами, вызовом одной функции, но в параметрах success, error, complete и beforeSend можно задавать массив функций, каждая из которых будет выполняться при запуске соответствующего события. Простой пример этого приведен ниже:

$(function() { $.ajax({ success: , beforeSend: function(jqxhr, settings) { settings.url = "mydata.json"; } }); function processData(data, status, jqxhr) { var template = $("#flowerTmpl"); template.tmpl(data.slice(0, 3)).appendTo("#row1"); template.tmpl(data.slice(3)).appendTo("#row2"); } function reportStatus(data, status, jqxhr) { console.log("Статус: " + status + " Код результата: " + jqxhr.status); } });

В этом примере для параметра success задан массив, состоящий из двух функций, одна из которых использует данные для добавления элементов в документ, а вторая выводит информацию на консоль.

Настройка контекста для событий

Параметр context позволяет указать элемент, который будет назначен переменной this, когда будет вызван обработчик события. Это может быть использовано для обращения к целевым элементам в документе без необходимости их выбора в функции-обработчике. Соответствующий пример приведен ниже:

$(function() { $.ajax({ success: function(data) { var template = $("#flowerTmpl"); template.tmpl(data.slice(0, 3)).appendTo("#row1"); template.tmpl(data.slice(3)).appendTo("#row2"); }, beforeSend: function(jqxhr, settings) { settings.url = "mydata.json"; }, context: $("h1"), complete: function(jqxhr, status) { var color = status == "success" ? "green" : "red"; this.css("border", "thick solid " + color); } }); });

Здесь параметр context устанавливается на объект jQuery, содержащий элементы h1 документа. В функции, определяемой параметром complete, мы выделяем рамкой выбранные элементы (в данном случае - элемент, поскольку в документе есть только один элемент h1) путем вызова метода css() для объекта jQuery (на который ссылаемся через this). Цвет рамки определяется на основании состояния запроса.

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

Настройка базовых параметров Ajax-запросов

Существует группа параметров, с помощью которых можно выполнить базовую настройку Ajax-запроса (некоторые из них, url и type, мы рассмотрели выше). Из всех доступных параметров они представляют наименьший интерес, и их имена в основном говорят сами за себя. Параметры, о которых идет речь, приведены в таблице ниже:

Базовые конфигурационные параметры Ajax-запроса Параметр Описание
accepts Устанавливает для запроса значение заголовка Accept, который указывает MIME-типы, поддерживаемые браузером. По умолчанию это значение определяется параметром dataType
cache Значение false указывает на то, что содержимое запроса не должно кэшироваться сервером. По умолчанию кешируются все типы данных, кроме script и jsonp
contentType Устанавливает для запроса значение заголовка content-туре
dataType Указывает, какие типы данных ожидаются от сервера. Если используется этот параметр, то jQuery будет игнорировать информацию, предоставляемую сервером о типе запроса
headers Задает дополнительные заголовки и значения, которые должны включаться в запрос
jsonp Задает строку, которую следует использовать вместо функции обратного вызова при выполнении запросов JSONP (кроссдоменные запросы). Этот параметр требует согласования с сервером
jsonpCallback Задает имя функции обратного вызова, которое должно использоваться вместо автоматически сгенерированного случайного имени, используемого jQuery по умолчанию
password Задает пароль, который должен использоваться в запросе при прохождении процедуры аутентификации
scriptCharset Указывает jQuery, какой набор символов используется при кодировании запрашиваемого JavaScript-содержимого
timeout Задает длительность тайм-аута (в миллисекундах) для запроса
userName Задает имя пользователя, которое должно использоваться в запросе при прохождении процедуры аутентификации
Задание тайм-аутов и заголовков

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

$(function() { $.ajax({ timeout: 5000, headers: { "X-HTTP-Method-Override": "PUT" }, success: function(data) { var template = $("#flowerTmpl"); template.tmpl(data.slice(0, 3)).appendTo("#row1"); template.tmpl(data.slice(3)).appendTo("#row2"); }, error: function(jqxhr, status, errorMsg) { console.log("Error: " + status); } }); });

В этом примере параметр timeout устанавливает максимальную длительность тайм-аута, равную 5 сек. Если запрос за это время не будет выполнен, то вызовется функция, заданная с помощью параметра error, и будет выведен код ошибки, определяемый параметром status.

Таймер запускается сразу же после передачи запроса браузеру, и большинство браузеров налагают ограничения на количество одновременно выполняющихся запросов. Это означает, что существует риск того, что к моменту истечения тайм-аута запрос даже не будет запущен. Чтобы избежать этого, необходимо располагать сведениями об ограничениях браузера, а также об объеме и ожидаемой длительности любых других выполняющихся Ajax-запросов.

Дополнительно в этом примере ниже используется параметр headers, с помощью которого в запрос добавляется заголовок. Для указания заголовков используется объект отображения данных. Используемый здесь заголовок может быть полезным для создания веб-приложений, поддерживающих архитектурный стиль REST, если только сервер правильно его распознает.

Использование дополнительных конфигурационных параметров

В следующих разделах описаны наиболее полезные и заслуживающие внимания дополнительные параметры, применимые к Ajax-запросам. Обычно они редко используются, но в случаях, когда в них возникает потребность, они оказываются незаменимыми. Эти параметры позволяют осуществлять точную настройку взаимодействия jQuery с Ajax.

Создание синхронных запросов

Управление режимом выполнения запросов осуществляется с помощью параметра async . Значение true, используемое для этого параметра по умолчанию, означает, что запрос будет выполняться в асинхронном режиме, тогда как значению false соответствует синхронный режим.

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

Игнорирование данных, оставшихся неизменными

С помощью параметра ifModified можно обеспечить получение данных лишь в том случае, если с момента последнего запроса они были изменены. Такое поведение определяется заголовком Last-Modified. Благодаря этому удается избежать бесполезной пересылки данных, которая не даст пользователю никакой новой информации по сравнению с той, которой он уже располагает. По умолчанию параметр ifModified имеет значение false, указывающее jQuery на необходимость игнорирования заголовка Last-Modified и предоставления данных в любом случае.

Пример использования этого параметра приведен ниже:

$(function() { $("button").click(function(e) { $.ajax("mydata.json", { ifModified: true, success: function(data, status) { if (status == "success") { $("#row1, #row2").children().remove(); var template = $("#flowerTmpl"); template.tmpl(data.slice(0, 3)).appendTo("#row1"); template.tmpl(data.slice(3)).appendTo("#row2"); } else if (status == "notmodified") { $("img").css("border", "thick solid green"); } } }); e.preventDefault(); }) });

В этом примере значение параметра ifModified устанавливается равным true. Функция success вызывается всегда, но если с того момента, когда содержимое запрашивалось в последний раз, оно не изменилось, то аргумент data будет иметь значение undefined, а аргумент status - значение notmodified .

В данном случае выполняемые действия определяются значением аргумента status. Если значением этого аргумента является success, то аргумент data используется для добавления элементов в документ. Если же аргумент status имеет значение notmodified, то мы используем метод css() для выделения рамкой элементов, которые уже имеются в документе.

В ответ на событие click, связанное с кнопкой, вызывается метод ajax(). Это дает возможность многократно повторять один и тот же запрос, чтобы продемонстрировать влияние параметра ifModified, как показано на рисунке:

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

Представьте, что вы запрашиваете данные, но в методе, указанном в параметре success, содержится ошибка, которая препятствует правильному обновлению содержимого документа. Тогда вашим следующим действием будет попытка щелкнуть на кнопке еще раз, чтобы добиться ожидаемого результата. Непродуманно используя параметр ifModified, можно проигнорировать действия пользователя, вынуждая его предпринимать более серьезные действия для устранения проблемы.

Обработка кода ответа

Параметр statusCode позволяет выбирать варианты дальнейших действий в зависимости от кода ответов на HTTP-запросы. Его можно использовать либо вместо параметров success и error, либо в дополнение к ним. Пример самостоятельного использования параметра statusCode приведен ниже:

$(function() { $.ajax({ url: "mydata.json", statusCode: { 200: function(data) { var template = $("#flowerTmpl"); template.tmpl(data.slice(0, 3)).appendTo("#row1"); template.tmpl(data.slice(3)).appendTo("#row2"); }, 404: function(jqxhr, status, errorMsg) { $("") .text("Статус: " + status + " Ошибка: " + errorMsg) .insertAfter("h1"); } } }); });

Здесь параметр statusCode задан в виде объекта, устанавливающего связь между кодами ответов на HTTP-запросы и соответствующими им функциями, которые должны быть выполнены на сервере. Какие именно аргументы передаются функциям, зависит от того, отражает ли код ответа успешное выполнение запроса или ошибку.

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

Как видите, это средство не дает непосредственной информации о кодах ответа. Я часто пользуюсь им в процессе отладки взаимодействия браузера с сервером, обычно для того, чтобы выяснить, почему jQuery ведет себя не так, как мне хотелось бы. При этом я использую параметр statusCode в дополнение к параметрам success и error и вывожу информацию на консоль. Если эти параметры используются совместно, то сначала будут выполнены функции success и error, а затем уже - функции, определяемые параметром statusCode.

Предварительная очистка ответных данных

С помощью параметра dataFilter можно задать функцию, которая будет вызвана для предварительной очистки данных, возвращаемых сервером. Это средство незаменимо в тех случаях, когда пересылаемые сервером данные не совсем вас устраивают либо из-за того, что отформатированы неподходящим образом, либо из-за того, что среди них есть данные, которые вы не хотите обрабатывать.

Это средство мне очень помогает при работе с серверами Microsoft ASP.NET, присоединяющими лишние данные к данным JSON. Удаление таких данных с помощью параметра dataFilter требует лишь минимальных усилий. Пример использования параметра dataFilter приведен ниже:

$(function() { $.ajax({ url: "mydata.json", success: function(data) { var template = $("#flowerTmpl"); template.tmpl(data.slice(0, 3)).appendTo("#row1"); template.tmpl(data.slice(3)).appendTo("#row2"); }, dataType: "json", dataFilter: function(data, dataType) { if (dataType == "json") { var filteredData = $.parseJSON(data); filteredData.shift(); return JSON.stringify(filteredData.reverse()); } else { return data; } } }); });

Функции передаются данные, полученные с сервера, и значение параметра dataType. Если параметр dataType не используется, то второму аргументу присваивается значение undefined. Ваша задача заключается в том, чтобы вернуть отфильтрованные данные. В этом примере предмет нашего внимания - данные в формате JSON:

Var filteredData = $.parseJSON(data); filteredData.shift(); return JSON.stringify(filteredData.reverse()); ...

Для повышения иллюстративности примера в нем выполняются некоторые дополнительные операции. Во-первых, данные JSON преобразуются в массив JavaScript с помощью метода jQuery parseJSON. Затем из массива удаляется первый элемент с помощью метода shift(), а порядок следования остальных его элементов обращается с помощью метода reverse().

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

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

Управление преобразованием данных

Рассмотрение одной из самых любимых своих настроек я приберег напоследок. Должно быть, вы обратили внимание, что при получении определенных типов данных jQuery автоматически выполняет некоторые удобные преобразования. Например, получая данные JSON, jQuery предоставляет функцию success, использующую объект JavaScript, а не исходную необработанную строку JSON.

Для управления подобными преобразованиями используется параметр converters . Значением этого параметра является объект, устанавливающий соответствие между типами данных и функциями, используемыми для их обработки. В примере ниже показано, как использовать этот параметр для автоматического преобразования HTML-данных в объект jQuery:

$(function() { $.ajax({ url: "flowers.html", // В этом примере мы загружаем HTML-разметку, а не данные в формате JSON success: function(data, status, jqxhr) { var elems = data.filter("div").addClass("dcell"); elems.slice(0, 3).appendTo("#row1"); elems.slice(3).appendTo("#row2"); }, converters: { "text html": function(data) { return $(data); } } }); });

В этом примере регистрируется функция для типа данных text html. Обратите внимание на пробел между компонентами указываемого MIME-типа (в отличие от формы записи text/html). Функция принимает данные, полученные от сервера, и возвращает преобразованные данные. В этом случае преобразование данных заключается в передаче HTML-фрагмента, содержащегося в файле flowers.html, функции $() и возврате результата. Отсюда следует, что к объекту, передаваемому в качестве аргумента data функции success, применимы обычные методы jQuery.

Работая с преобразователями данных, можно слишком увлечься. Я всегда стараюсь избегать соблазна делать с помощью этих функций больше, чем следует. Например, иногда меня так и тянет применить к данным JSON шаблон и передать обратно полученные в результате HTML-элементы. И хотя этот прием очень удобен, он сослужит плохую службу, если кто-то другой будет пытаться расширить ваш код или, например, вам самому впоследствии потребуется организовать интенсивную обработку данных для получения их в исходной форме.

Настройка и фильтрация Ajax-запросов

После того как вы познакомились с методом ajax() и доступными для работы с ним параметрами, мы можем рассмотреть несколько дополнительных методов, предоставляемых jQuery для упрощения настройки запросов.

Определение параметров, используемых по умолчанию

Метод ajaxSetup() позволяет установить значения параметров, которые будут применяться по умолчанию во всех Ajax-запросах, тем самым освобождая вас от необходимости настраивать параметры при каждом запросе. Пример использования этого метода приведен ниже:

") .text("Статус: " + status + " Ошибка: " + errorMsg) .insertAfter("h1"); }, converters: { "text html": function(data) { return $(data); } } }); $.ajax({ url: "flowers.html", success: function(data, status, jqxhr) { var elems = data.filter("div").addClass("dcell"); elems.slice(0, 3).appendTo("#row1"); elems.slice(3).appendTo("#row2"); } }); });

Метод ajaxSetup() вызывается с помощью функции jQuery $ аналогично тому, как это делалось в случае вызова метода ajax(). Аргументом метода ajaxSetup() является объект, содержащий значения параметров, которые вы хотите использовать по умолчанию для всех Ajax-запросов. В этом примере мы устанавливаем значения по умолчанию для параметров timeout, global, error и converters.

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

Фильтрация запросов

Метод ajaxSetup() определяет базовые значения конфигурационных параметров, применимые ко всем запросам Ajax. Возможности динамической настройки параметров для отдельных Ajax-запросов обеспечиваются методом ajaxPrefilter() . Пример использования этого метода приведен ниже:

$(function() { $.ajaxSetup({ timeout: 15000, global: false, error: function(jqxhr, status, errorMsg) { $("") .text("Статус: " + status + " Ошибка: " + errorMsg) .insertAfter("h1"); }, converters: { "text html": function(data) { return $(data); } } }); $.ajaxPrefilter("json html", function(settings, originalSettings, jqxhr) { if (originalSettings.dataType == "html") { settings.timeout = 2000; } else { jqxhr.abort(); } }) $.ajax({ url: "flowers.html", dataType: "html", success: function(data, status, jqxhr) { var elems = data.filter("div").addClass("dcell"); elems.slice(0, 3).appendTo("#row1"); elems.slice(3).appendTo("#row2"); } }); });

Указанная вами функция будет выполняться для каждого нового Ajax-запроса. Аргументами, передаваемыми функции, являются параметры запроса (включая любые значения по умолчанию, установленные вами с помощью метода ajaxSetup()), а также исходные параметры, переданные методу ajax() (исключая любые значения по умолчанию) и объекту jqXHR запроса.

Мы вносим изменения в объект, передаваемый в качестве первого аргумента, как показано в примере. В данном сценарии, если среди параметров, передаваемых методу ajax(), присутствует параметр dataType, то длительность тайм-аута устанавливается равной двум секундам. Чтобы предотвратить отправку всех остальных запросов, для объекта jqXHR вызывается метод abort().

Знаете ли Вы, что такое мысленный эксперимент, gedanken experiment?
Это несуществующая практика, потусторонний опыт, воображение того, чего нет на самом деле. Мысленные эксперименты подобны снам наяву. Они рождают чудовищ. В отличие от физического эксперимента, который является опытной проверкой гипотез, "мысленный эксперимент" фокуснически подменяет экспериментальную проверку желаемыми, не проверенными на практике выводами, манипулируя логикообразными построениями, реально нарушающими саму логику путем использования недоказанных посылок в качестве доказанных, то есть путем подмены. Таким образом, основной задачей заявителей "мысленных экспериментов" является обман слушателя или читателя путем замены настоящего физического эксперимента его "куклой" - фиктивными рассуждениями под честное слово без самой физической проверки.
Заполнение физики воображаемыми, "мысленными экспериментами" привело к возникновению абсурдной сюрреалистической, спутанно-запутанной картины мира. Настоящий исследователь должен отличать такие "фантики" от настоящих ценностей.

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

Это мы видим на примере СТО и ОТО, превратившихся в своеобразный вид религии, управляющей наукой и общественным мнением. Никакое количество фактов, противоречащих им, не может преодолеть формулу Эйнштейна: "Если факт не соответствует теории - измените факт" (В другом варианте " - Факт не соответствует теории? - Тем хуже для факта").

Максимально, на что может претендовать "мысленный эксперимент" - это только на внутреннюю непротиворечивость гипотезы в рамках собственной, часто отнюдь не истинной логики заявителя. Соответсвие практике это не проверяет. Настоящая проверка может состояться только в действительном физическом эксперименте.

Эксперимент на то и эксперимент, что он есть не изощрение мысли, а проверка мысли. Непротиворечивая внутри себя мысль не может сама себя проверить. Это доказано Куртом Гёделем.

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

Разработка кода для JavaScript для реализации AJAX с нуля является весьма трудоемким и нудным процессом. Однако множество библиотек JavaScript, включая jQuery , имеют отличную высокоуровневую реализацию AJAX в виде набора методов и функций, которые облегчают и ускоряют построение веб сайтов.

В данной серии уроков мы рассмотрим основы построения запросов AJAX с помощью jQuery. Будут раскрыты следующие темы:

  • Что такое технология AJAX? Как она работает? В чем ее преимущества?
  • Как выполнить различные типы запросов AJAX с помощью jQuery?
  • Отправка данных на сервер с помощью запросов AJAX.
  • Обработка и выделение данных из ответов AJAX с сервера.
  • Как настроить обработку AJAX в jQuery и изменить установки по умолчанию?

Примечание: Уроки сконцентрированы на части JavaScript клиентской стороны. Но разработка серверной части также достаточно проста. Для более полной информации следует изучить материалы по языкам программирования серверной стороны, например PHP.

Что такое AJAX и чем он полезен?

AJAX является техникой разработки веб приложений, в которых JavaScript код, выполняющийся в браузере посетителя, связывается с веб сервером асинхронно , то есть в фоновом режиме. Отличие от обычных веб приложений заключаются в следующем:

  • Обычная веб страница содержит ссылки или формы, которые при нажатии или отправке создают запрос к новому адресу URL на веб сервере. Сервер отправляет полностью новую страницу HTML, которую затем выводит браузер, заменяя оригинальную страницу. Такой подход занимает много времени и плохо действует на посетителя, так как тому приходится ждать загрузки новой страницы.
  • При использовании технологии AJAX, JavaScript код делает запрос к URL на сервере. Код также может отправить данные вместе с запросом. Затем JavaScript код обрабатывает ответ сервера и действует соответствующим образом. Например, могут быть произведены вычисления с возвращаемыми данными, добавлен или обновлен виджет на странице, выдано сообщение посетителю об обновлении базы данных на сервере.

Так как запрос AJAX выполняется в фоновом режиме, то код JavaScript (и посетитель) может продолжать работу со страницей во время обработки запроса. Процесс скрыт от посетителя, которому не нужно покидать страницу, которую он просматривает в данный момент времени. Такой подход делает страницы с AJAX очень приятными в работе.

Фундаментальным моментом AJAX является объект JavaScript XMLHttpRequest . Он предоставляет ряд методов, таких как open() , send() и onreadystatechange() , которые могут быть использованы при отправке запросов AJAX на сервер и обработке ответов в фоновом режиме.

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

Для тех кто более любопытен, слово AJAX является аббревиатурой из первых букв выражения на английском языке "A synchronous J avaScript A nd X ML" (Асинхронный JavaScript и XML). Однако, термин может ввести в заблуждение - запрос не обязательно должен быть асинхронным и необязательно использовать XML для отправки данных.

Делаем запрос GET с помощью $.get()

Метод jQuery $.get() предоставляет легкий и удобный способ сделать простой запрос AJAX. Он выполняет запрос с помощью метода HTTP GET (используется для получения URL, например страниц и изображений), вместо метода POST (который традиционно используется для отправки данных формы).

В простейшей форме можно вызвать метод так:

Где url является адресом URL ресурса, от которого ожидается ответ. Обычно это скрипт на стороне сервера, который выполняет какие-нибудь действия и может возвращать некие данные:

$.get("http://example.com/getForecast.php");

Хотя можно также запросить статический документ:

$.get("http://example.com/mypage.html");

При запросе URL, вы можете отправить данные с запросом. Вы можете передать данные в строке запроса, так же как и при обычном запросе GET:

$.get("http://example.com/getForecast.php?city=rome&date=20120318");

Корректно будет сделать то же самое передав объект данных в качестве второго параметра методу $.get() . Объект данных должен содержать информацию в виде пар имя свойства/значение свойства. Например:

Var data = { city: "rome", date: "20120318" }; $.get("http://example.com/getForecast.php", data);

В качестве альтернативы вы можете передать данные методу $.get() как строку:

Var data = "city=rome&date=20120318"; $.get("http://example.com/getForecast.php", data);

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

До сих пор мы рассматривали примеры использования $.get() только для отправки запросов на сервер, игнорируя любой ответ, который может сформировать скрипт на серверной стороне. Но в большинстве случаев ваш JavaScript код будет ожидать ответ от скрипта на серверной стороне и обрабатывать полученные данные.

AJAX запрос - асинхронный , что означет его выполнение в фоновом режиме, когда остальной код JavaScript продолжает действовать. Как же в таком случае получать ответ от сервера, когда завершится запрос?

Вам нужно написать возвратную функцию , которая будет автоматически выполняться по завершению запроса AJAX и отправке ответа сервером. Как минимум, ваша функция должна принимать данные, возвращаемые сервером, как свой первый аргумент:

Function myCallback(returnedData) { // Делаем обработку данных returnedData }

Как только возвратная функция создана, вы можете передать ее в качестве третьего аргумента в метод $.get() :

Var data = { city: "rome", date: "20120318" }; $.get("http://example.com/getForecast.php", data, myCallback);

Определяем тип данных ответа

Обычно, серверная сторона передает данные в одном из нескольких типовых форматов, включая XML , JSON , JavaScript, или HTML. По умолчанию jQuery пытается определить наиболее подходящий формат и разобрать данные соответствующим образом. Но лучше явно определить формат.

Для указания формата надо передать четвертый аргумент методу $.get() . Данный аргумент может быть строкой из следующего списка:

  • "xml"
  • "json"
  • "script"
  • "html"

Например, если вы знаете, что скрипт сервера возвращает данные в формате JSON, то вызываете метод $.get() следующим образом:

$.get("http://example.com/getForecast.php", data, myCallback, "json");

Пример использования метода $.get()

Здесь приводится пример создания запроса AJAX с помощью метода $.get() и простая обработка ответа. Для работы примера нужно на сервере создать простой текстовый файл с именем getForecast.txt , содержащий следующий текст:

{ "city": "Васюки", "date": "18 марта 2012", "forecast": "Зубодробительный холод и слякоть", "maxTemp": +1 }

Данный файл будет имитировать ответ в формате JSON, который мог быть сформирован скриптом прогноза погоды на сервере.

Затем создаем страницу showForecast.html в той же папке что и getForecast.txt:

Прогноз погоды $(function() { $("#getForecast").click(function() { var data = { city: "Васюки", date: "20120318" }; $.get("getForecast.txt", data, success, "json"); }); function success(forecastData) { var forecast = forecastData.city + " прогноз на " + forecastData.date; forecast += ": " + forecastData.forecast + ". Максимальная температура: " + forecastData.maxTemp + "C"; alert(forecast); } }); Получить прогноз погоды

Открываем showForecast.html в браузере и нажимаем кнопку "Получить прогноз погоды". В окне сообщения получим прогноз погоды с нашего сервера.

Вот как работает данный код:

  • showForecast.html содержит элемент button "Получить прогноз погоды" с ID getForecast .
  • JavaScript вверху страницы выполняется как только страница будет загружена и DOM окажется в состоянии готовности.
  • Код JavaScript сначала привязывает обработчик события click к кнопке #getForecast . Данный обработчик выполняет AJAX запрос GET к getForecast.txt , передавая название города и дату для прогноза. Также определяется возвратная функция success(), которая будет выполняться по завершению запроса. Формат возвращаемых сервером данных определяется как JSON.
  • Файл getForecast.txt возвращает браузеру данные прогноза в формате JSON.
  • Вызывается функция success() . jQuery разбирает данные JSON, полученные от getForecast.txt , конвертирует их в объект JavaScript, и передает их в функцию.
  • Функция возвращает объект данных forecastData и выводит сообщение, которое содержит несколько свойств объекта, включая название города, прогноз и температуру.
  • Простой пример в несколько строк демонстрирует работу запроса AJAX с использованием метода $.get() .

    От автора: данная серия статей призвана познакомить front-end дизайнеров и начинающих разработчиков с технологией AJAX, основной front-end технологией. В первом уроке мы затронем основы AJAX, начнем узнавать различные детали данной технологии, узнаем, что это такое, как работает и какие есть ограничения.

    Приступим! Обратите внимание: предполагается, что вы уже знаете базовые front-end технологии, такие как HTML и CSS.

    Что такое AJAX?

    AJAX расшифровывается как «Асинхронный JavaScript и XML». Под AJAX понимается не одна технология, и она не является новой. На самом деле это группа технологий (HTML, CSS, Javascript, XML, и т.д.), которые связываются вместе для создания современных веб-приложений.

    С помощью AJAX клиент (браузер) общается с сервером и запрашивает у него данные. Полученный ответ обрабатывается, и в станицу вносятся изменения без полной ее перезагрузки. Разберем аббревиатуру AJAX:

    «Асинхронный» означает, что когда клиент запрашивает данные с сервера, браузер не зависает, пока не получит ответ. Пользователь наоборот может перемещаться по страницам. Как только сервер вернул ответ, в фоновом режиме ответ начинает обрабатываться соответствующими функциями.

    «JavaScript» это язык программирования, который используется для создания объекта запроса AJAX, парсинга этого ответа и обновления DOM страницы.

    Для отправки запроса на сервер клиент использует XMLHttpRequest или XHR API. API (программный интерфейс) это набор методов, которые задают правила общения между двумя заинтересованными сторонами. Тем не менее, приходящие из AJAX запроса данные могут быть в любом формате, а не только в XML.

    Как работает AJAX

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

    На картинке описан стандартный AJAX сценарий:

    Пользователь хочет увидеть больше статей, и он или она кликает на нужную кнопку. Данное событие запускает вызов AJAX.

    Запрос посылается на сервер. С запросом можно передать различные данные. Запрос может посылаться в статический файл (к примеру, example.php), хранящийся на сервере. Также можно выполнять динамические скрипты (functions.php), на каждом этапе которых будет происходить общение с базой данных (или другой системой) для извлечения необходимой информации.

    База данных отсылает обратно запрошенные статьи на сервер. А сервер посылает их в браузер.

    JavaScript парсит ответ и обновляет часть DOM (структура страницы). В нашем примере обновится только сайдбар. Остальные части страницы не меняются.

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

    Живой пример на AJAX

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

    Сперва рассмотрим принципы работы Facebook и Twitter. При прокрутке страницы вниз AJAX подгружает новый контент. Также если вы ставите лайк или дизлайк вопросам и ответам на Stack Overflow, опять же срабатывает AJAX. Как только вы вбиваете в строку поиска что-то в Google или Youtube, срабатывают множественные запросы AJAX.

    Более того, если мы захотим, то сможем отслеживать данные запросы. К примеру, в консоли Chrome это можно сделать, кликнув правой кнопкой мыши и активировав функцию Log XMLHttpRequests.

    Как создать запрос

    Выше мы уже говорили, что для создания запроса используется XMLHttpRequest API. Кроме того в jQuery, самой популярной JS библиотеке есть различные Ajax функции и методы. В серии статей мы рассмотрим различные примеры на чистом JS и JQuery для отправки запросов на сервер.

    Управление запросами

    Вытаскиваемые данные с сервера могут храниться в различных форматах. XML, JSON, JSONP, обычный текст и HTML.

    XML

    XML (Расширяемый язык разметки) – один из самых популярных форматов для обмена данными между приложениями. Формат похож на HTML, и в качестве структуры используются теги. Однако в XML нет готовых тегов, мы сами задаем их. Пример структуры ниже:

    Mike Mathew Australian English Spanish French Russian

    < person >

    < name > Mike < / name >

    < surname > Mathew < / surname >

    < nationality > Australian < / nationality >

    < languages >

    < language > English < / language >

    < language > Spanish < / language >

    < language > French < / language >

    < language > Russian < / language >

    < / languages >

    < / person >

    В сети полно онлайн редакторов, с помощью которых можно создавать XML документы. Мой любимый это: XMLGrid.net. В этом редакторе наш пример выглядит так:

    JSON

    JSON (JavaScript Object Notation) – еще один популярный формат обмена данными. В JSON пример сверху будет выглядеть так:

    { "name" : "Mike", "surname" : "Mathew", "nationality" : "Australian", "languages" : ["English", "Spanish", "French", "Russian"] }

    "name" : "Mike" ,

    , JSON Editor Online

    В JSN редакторе наш пример будет выглядеть так:

    Ограничения в AJAX запросах

    Перед тем, как начать использовать AJAX, необходимо узнать про ограничения. Мы рассмотрим только две проблемы.
    Первая – ошибка в консоли Chrome:

    Ошибка появляется, когда запрос ссылается на локальный файл. В этом примере мы хотели получить доступ к данным из локального файла (Demo.json), который хранится не на сервере. Для устранения данной проблемы можно установить локальный сервер и хранить файлы там. Вторая проблема:

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

    Один из способов это CORS от W3C. Но данный механизм требует внести изменения в конфигурацию файлов на сервере. К примеру, на данной странице описано, как настроить Apache сервер. Другой способ это JSONP (JSON с набивкой).

    Заключение

    Данный обзор дал вам представление о том, что такое AJAX, где вы уже с ним могли сталкиваться, а также какие существуют потенциальные проблемы. Также мы рассмотрели самые популярные форматы обмена данными. В следующей статье мы рассмотрим работающий пример. Увидимся!

    AJAX расшифровывается как Asynchronous Javascript And XML, что означает Асинхронный JavaScript и XML. AJAX позволяет обновлять данные HTML-страницы без полной её перезагрузки. Кроме этого технология позволяет работать с интернет-страницами асинхронно. То есть пока JavaScript взаимодействует с Web-сервером, пользователь может продолжать работать с web-страницей.

    Примером использования технологии AJAX является Google Suggest . Работа Google Suggest заключается в том, что пока вы вводите слово или фразу для поиска, JavaScript обращается к базе данных Google и запрашивает у неё 10 самых популярных запросов, начинающихся с тех же букв. И затем выводит этот список без перезагрузки страницы.

    Для рассмотрения принципов работы технологии AJAX, реализуем на своем сайте механизм подобный Google Suggest. Допустим, у нас есть сайт туроператора. На сайте есть поле поиска предложений по названию страны. Добавим к этому полю раскрывающийся список с автозаполнением по введенным буквам. Приступим к решению этой задачи. Сразу оговорюсь, что для реализации этой задачи необходимо знание HTML и немного JavaScript(знатоком быть не обязательно). В качестве серверного языка будет использован php.

    Для начала создадим форму поиска. Для этого на вашем web-сервере создайте файл index.html, откройте его при помощи любого текстового редактора и введите следующий html-код.




    Поиск предложений.





    Отдых на море

    Поиск предложений:








    В этом листинге мы создали форму поиска с полем для ввода текста и кнопкой отправки, и создаем слой div для вывода результатов. К данной странице так же прикрепляется файл ajax.js, который будет содержать функции JavaScript.

    Далее напишем функции JavaScript, которые будут посылать запросы серверу и обновлять страничку. Для того чтобы не приходилось перегружать html-документ полностью нам и понадобиться технология Ajax. Итак, приступим. Создайте файл ajax.js, поместите его в ту же папку, что и index.html, и откройте его в текстовом редакторе.

    Для начала необходимо создать объект, который будет передавать запросы серверу и принимать ответы. В разных браузерах этот объект создается по разному. Мы напишем универсальную функцию, которая должна работать в разных браузерах. Добавьте в файл ajax.js следующий код JavaScript.

    /*переменная для хранения объекта запроса*/
    var request;
    /*функция создания объекта запроса*/
    function CreateRequest()
    {
    var request=null;
    try
    {
    //создаем объект запроса для Firefox, Opera, Safari
    request = new XMLHttpRequest();
    }
    catch (e)
    {
    //создаем объект запроса для Internet Explorer
    try
    { request=new ActiveXObject("Msxml2.XMLHTTP");
    }
    catch (e)
    {
    request=new ActiveXObject("Microsoft.XMLHTTP");
    }
    }
    return request;
    }

    Выводить список результатов необходимо при каждом изменении в поле поиска. Для этого воспользуемся обработчиком событий JavaScript. Определять изменения будем при каждом событии клавиатуры keyup . Для этого в наш HTML-код файла index.html в строке, где создается поле поиска с именем country , добавим атрибут onkeyup="KeyPress(this.value)" :

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

    • Создать новый объект запроса посредством вызова функции CreateRequest();
    • Сформировать URL-адрес, к которому необходимо подключиться для получения результатов;
    • Настроить объект запроса для установки связи с сервером;
    • Отправить запрос серверу.

    Приступим к созданию функции KeyPress() . Для создания нового объекта запроса нам просто необходимо переменной request присвоить значение, возвращаемое ранее созданной функцией CreateRequest() . И для надежности проверим переменную request . Если она равна NULL , то объект запроса создать не удалось. Вот так будет выглядеть код JavaScript для решения данной задачи:

    Function KeyPress(term) {
    request=CreateRequest();

    if(request==null)
    {
    return;
    }
    }

    Далее необходимо указать объекту запроса request какая функция JavaScript будет обрабатывать ответ сервера. Для этого необходимо свойству onreadystatechange присвоить имя соответствующей функции. Данное свойство указывает браузеру, какую функцию запускать при каждом изменении состояния готовности запроса. У нас обработкой ответа будет заниматься функция LoadResults() . Добавьте в функцию следующую строку: request.onreadystatechange = LoadResults; . Отметим, что после названия функции нет скобок.

    Затем займемся настройкой подключения. Для этого сначала необходимо указать объекту, куда передавать этот запрос. Сформируем URL-адрес сценария, который будет вычислять результаты, и присвоим его переменной url . Допустим, за вычисление результатов на стороне сервера у нас будет отвечать php-скрипт country.php . Тогда наш URL-адрес будет выглядеть следующим образом: var url = "country.php" + "?s=" + encodeURIComponent(term) + "&sid=" + Math.random(); , где с переменной s передаются введенные в поле поиска символы, а sid присваивается случайное число, чтобы браузер не кэшировал страницу. Добавьте эту строчку в тело функции KeyPress() .

    Далее необходимо инициализировать подключение с помощью метода open("GET", url, true) объекта request . Этот метод имеет три параметра. Параметр "GET" указывает, как отправить данные серверу. Мы используем метод GET , потому что введенные символы в строку поиска передаются серверному сценарию через url-адрес. Во второй параметре указывается url-адрес серверного сценария. У нас url-адрес храниться в переменной url , поэтому во втором параметре мы указываем эту переменную. Третий параметр может иметь два значения: true - асинхронный режим и false - синхронный режим. Наше приложение будет работать в асинхронном режиме, поэтому указываем true . После инициализации подключения, необходимо создать подключение и запросить результаты. Для этого просто необходимо вызвать функцию send(null) объекта request . Параметр null указывает, что запрос не содержит данных.

    После внесения всех изменений функция KeyPress(this.value) примет следующий вид:

    Function KeyPress(term)
    {
    /*создаем новый объект запроса*/
    request=CreateRequest();
    /*если не удалось создать объект запроса, то заканчиваем выполнение функции*/
    if(request==null)
    {
    return;
    }
    /*формируем url-адрес*/
    var url = "country.php" + "?s=" + encodeURIComponent(term) + "&sid=" + Math.random();
    /*настраиваем объект запроса для установки связи*/
    request.onreadystatechange = LoadResults;
    request.open("GET", url, true);
    /*отправляем запрос серверу*/
    request.send(null);
    }

    Итак, соединение установлено, запрос отправлен, сервер обрабатывает данные и возвращает результат. Далее необходимо получить ответ, обработать и вывести результаты на web-страницу. Всем этим будет заниматься функция LoadResults() , которая будет вызываться при каждом изменении статуса готовности запроса. Рассмотрим, как должна работать эта функция.

    Для начала необходимо проверить текущее состояние готовности. Статус готовности хранит свойство объекта запроса readyState . При завершении обработки запроса состояние готовности равно 4. Т.е. если request.readyState == 4 , то можно обрабатывать ответ:

    Function LoadResults()
    {


    /*обрабатываем ответ*/
    }
    }

    Function LoadResults()
    {
    /*Проверяем состояние готовности*/
    if (request.readyState == 4){
    /*Проверяем статус запроса*/
    if (request.status == 200){
    /*все в порядке, обрабатываем ответ*/
    }
    }
    }

    Если проверка состояния и статуса запроса закончилась успешно, то можно приступать к обработке данных, полученных от сервера. Получить данные можно двумя способами: request.responseText - получение данных в виде текста, либо request.responseXML - получение данных в виде объекта XMLDocument. Допустим, у нас сервер передает ответ в виде текстового списка стран через запятую. Тогда получаем данные: var answer = request.responseText . Далее обрабатываем данные и выводим их в слой с id="searchresults" .

    Я не буду вдаваться в подробности обработки данных, а просто приведу код функции с комментариями:

    Function LoadResults()
    {
    /*Проверяем состояние готовности*/
    if (request.readyState == 4){
    /*Проверяем статус запроса*/
    if (request.status == 200){
    //делаем слой searchresults видимым
    ShowDiv("searchresults");
    //очищаем результаты
    ClearResults();
    //получаем данные
    var answer = request.responseText;
    //преобразуем строку текста в массив
    var array = answer.split(",");
    //определяем размер массива
    var count = array.length;
    //находим слой searchresults

    //создаем таблицу в объектной модели документа
    var tbl = document.createElement("table");
    var tblbody = document.createElement("tbody");
    var tblRow, tblCell, tblNode;
    //перебираем все элементы массива array
    for(var i = 0; i {
    var text = array[i];
    //создаем строки таблицы и добавляем в ее тело
    tblRow = document.createElement("tr");
    tblCell = document.createElement("td");
    //задаем атрибуты и функции ячеек
    tblCell.onmouseover = function(){this.className="mouseOver";};
    tblCell.onmouseout = function(){this.className="mouseOut";};
    tblCell.setAttribute("border", "0");
    tblCell.onclick = function(){Replace(this);};
    tblNode = document.createTextNode(text);
    tblCell.appendChild(tblNode);
    tblRow.appendChild(tblCell);
    tblbody.appendChild(tblRow);
    }
    //добавляем в таблицу ее тело
    tbl.appendChild(tblbody);
    //помещаем таблицу в слой
    div.appendChild(tbl);
    }
    }
    }

    И еще пару вспомогательных функций JavaScript для вывода результатов на экран:

    /*делаем слой с результатами видимым*/
    function ShowDiv(id)
    {
    if (document.layers) document.layers.visibility="show";
    else document.getElementById(id).style.visibility="visible";
    }

    /*делаем слой с результатами не видимым*/
    function HideDiv(id)
    {
    if (document.layers) document.layers.visibility="hide";
    else document.getElementById(id).style.visibility="hidden";
    }

    /*очистка результатов*/
    function ClearResults()
    {
    /* Удаление существующих строк из таблицы результатов
    var div = document.getElementById("searchresults");
    var counter = div.childNodes.length;
    for(var i = counter-1; i >= 0; i--)
    {
    div.removeChild(div.childNodes[i]);
    }
    }

    /*Заменяем значение в поле ввода значением, выбранным щелчком мыши*/
    function Replace(tblCell)
    {
    var inputbox = document.getElementById("country");
    inputbox.value = tblCell.firstChild.nodeValue;
    ClearResults();
    HideDiv("searchresults");
    }

    Так же в наш html-файл index.html между тегами и добавьте следующие правила CSS:


    .mouseOut{ background: #ffffff; color: #0000000; }
    .mouseOver{ background: #ccccff; color: #0000000; }
    table {width:250px }

    На этом все. В данной статье мы рассмотрели основы работы технологии Ajax на примере.