Ajax — ajax асинхронный


Содержание

jQuery и Ajax

— это сокращение от «Asynchronous JavaScript and XML» (асинхронный JavaScript и XML), но в наши дни этот термин употребляется как самостоятельный, без приписывания ему какого-либо смысла в результате расшифровки названия.

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

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

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

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

Кратко об Ajax

Если вы новичок в Ajax, позвольте вкратце рассказать вам о том, что такое асинхронные запросы. Это важно знать, поскольку асинхронные запросы занимают в Ajax центральное место, а буква А в Ajax происходит от слова asynchronous.

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

Если же задача выполняется асинхронно, то вы сообщаете браузеру, что намерены выполнить определенную работу в фоновом режиме. Выражение «в фоновом режиме» звучит довольно туманно, но для браузера оно означает следующее: «Выполни это так, чтобы пользователь в течение всего времени мог взаимодействовать с документом, и сообщи мне, когда все будет сделано».

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

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

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

Выполнение GET-запросов Ajax

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

Этот код (файл test.html) аналогичен тому, который использовался в предыдущих примерах, но в нем отсутствуют элементы, описывающие отдельные виды цветочной продукции, а также элементы данных и шаблоны, с помощью которых они генерируются. Вместо этого создан отдельный файл под названием flowers.html:

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

Для тестирования всех приведенных ниже и в следующей статье примеров, вы должны сохранить оба этих файла на локальном сервере. Если вы еще не установили локальный сервер, рекомендую WAMP сервер EasyPHP.

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

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

Здесь используется метод get(), которому передаются два аргумента. Первый из них — это URL-адрес, указывающий на документ, который мы хотим загрузить. В данном случае используется адрес flowers.html, который будет интерпретироваться как URL, заданный относительно URL-адреса, использующегося для загрузки основного документа.

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

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

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

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

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

Функция, выполняющаяся в случае успешного завершения запроса, принимает в качестве аргумента данные, отправленные сервером в ответ на запрос. В этом примере мы получаем содержимое файла flowers.html, представляющее собой HTML-фрагмент. Чтобы превратить этот фрагмент в объект, с которым можно работать средствами jQuery, мы передаем его функции $(), которая выполнит синтаксический анализ фрагмента и сгенерирует дерево объектов HTMLElement, как показано в примере ниже:

Как уже отмечалось, из элементов div были намеренно удалены атрибуты class. Теперь, как видите, мы восстанавливаем их с помощью стандартного метода addClass(). Передав данные функции $(), мы получаем от нее объект jQuery, с которым далее можем работать как с любым другим объектом. Мы добавляем элементы в документ с помощью методов slice() и appendTo().

Обратите внимание на то, что для выбора элементов div, сгенерированных на основе полученных от сервера данных, используется метод filter(). Дело в том, что в процессе синтаксического анализа символы перевода строки, введенные между элементами div в файле flowers.html для структурирования данных, jQuery воспринимает как текстовое содержимое и вставляет вместо них текстовые элементы. Чтобы этого избежать, необходимо либо проследить за тем, чтобы эти символы отсутствовали в запрашиваемом документе, либо удалить их, используя метод filter().

Повышение наглядности процесса загрузки

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

Теперь документ flowers.html не будет загружаться до тех пор, пока на кнопке «Ajax» не будет выполнен щелчок, причем каждый последующий щелчок также будет приводить к добавлению в документ дополнительных элементов, как показано на рисунке:

Обратите внимание на вызов метода preventDefault() для объекта Event, который передается в обработчик событий. Это делается для того, чтобы отменить выполнение браузером действий, предусмотренных по умолчанию. Поскольку элемент button содержится внутри элемента form, действием по умолчанию является отправка формы на сервер.

Получение других типов данных

Возможности метода get() не ограничиваются работой только с HTML. Он позволяет получать с сервера данные любой природы. Особый интерес для нас представляет формат JSON, предоставляющий удобные возможности для обработки данных средствами jQuery.

В свое время, когда технология Ajax еще только начинала широко внедряться, предпочтительным форматом данных считался XML, и даже буква X в аббревиатуре «Ajax» обязана своим происхождением этому формату. Я не собираюсь подробно обсуждать XML и лишь замечу, что этот язык страдает избыточностью синтаксиса, трудно читается и требует относительно больших затрат времени и ресурсов для генерации и обработки данных.

В последние годы формат XML был заметно потеснен форматом JSON (JavaScript Object Notation), отличающимся простотой и исключительной приспособленностью для работы с JavaScript-кодом (о чем говорит уже само его название). Специально для этого примера я создал файл mydata.json и сохранил его вместе с файлом test.html на веб-сервере. Содержимое файла mydata.json представлено в примере ниже:

В этом файле содержатся данные для различных видов цветочной продукции, и несложно заметить, что форма представления данных JSON совпадает с формой представления данных, встраиваемых в JavaScript-код. Это и есть одна из причин, по которым формат JSON вытеснил XML в веб-приложениях.

Для загрузки и обработки этих данных с помощью Ajax можно использовать метод get(), как показано в примере ниже (здесь мы используем шаблоны данных, вам потребуется добавить ссылку на библиотеку jquery.tmpl.js):

В этом примере файл с данными JSON запрашивается с сервера после щелчка на кнопке. Полученные данные передаются функции так, как если бы это был обычный HTML-фрагмент. Для обработки данных и генерации из них HTML-элементов используется подключаемый модуль шаблонов, а для вставки элементов в документ — методы slice() и appendTo(). Обратите внимание на то, что мы не предпринимаем никаких действий для того, чтобы преобразовать строку JSON в объект JavaScript — за нас это автоматически делает jQuery.

Некоторые веб-серверы (например Microsoft IIS 7.5) не возвращают содержимое браузеру, если не могут распознать расширение имени файла или формат данных. Чтобы этот пример работал с IIS, мне пришлось установить новое соответствие между расширением имени файла (.json) и MIME-типом данных в формате JSON (application/json). Пока я этого не сделал, веб-сервер IIS отвечал на мой запрос файла mydata.json сообщением с кодом 404 («Not Found»).

Передача данных GET-запросам

Данные могут пересылаться на сервер в составе GET-запросов, для отправки которых можно использовать методы get(), load(), getScript() и getJSON(). Соответствующий пример приведен ниже:

Предоставленные вами данные присоединяются к указанному URL-адресу в виде строки запроса. Это означает, что запрос имеет примерно следующий вид:

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

Выполнение POST-запросов Ajax

Теперь, когда вы уже знаете, как получать данные с сервера, можно перейти к рассмотрению вопроса о способах отправки данных, точнее — отправки данных формы на сервер. Для решения этой задачи также предусмотрен прямой метод post(), значительно упрощающий отправку данных формы. Прежде чем перейти к рассмотрению данного метода, вы должны настроить свой сервер.

Серверный сценарий

Для этого раздела вам понадобится серверный сценарий, который будет получать данные, отправленные браузером с использованием HTTP-метода POST, выполнять простую операцию с использованием этих данных и генерировать ответ. Сценарий PHP (вы можете написать собственный сценарий для своей платформы) для этого раздела приведен в примере ниже:

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

Возвращаемый объект JSON чрезвычайно прост: он содержит общее количество единиц продукции, выбранной пользователем, и количество заказанных единиц по тем видам продукции, для которых оно указано. Таким образом, если выбрать одну астру, два нарцисса и две розы, то ответ в формате JSON, отправляемый сервером, будет выглядеть так:

Ранее формат JSON использовался нами для представления массива объектов, тогда как данный серверный сценарий возвращает одиночный объект, свойства которого соответствуют выбранным видам цветов. Свойство total содержит общее количество выбранных цветов. Должен признать, что подобного рода операции слишком просты для того, чтобы дать полное представление о возможностях обработки данных на сервере, но все же основной предмет нашего рассмотрения — Ajax, а не вопросы разработки серверных приложений.

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

Итак, теперь, когда вы уже имеете подготовленный сервер, можем приступить к использованию метода post() для оправки данных формы на сервер, как показано в примере ниже:

Этот пример кажется немного сложнее, чем он есть на самом деле. Мы начинаем с того, что используем метод getJSON() для получения файла mydata.json, содержащего описание цветочной продукции, после чего генерируем элементы с помощью шаблона данных и добавляем их в документ. В результате мы оказываемся на уже хорошо вам знакомой исходной позиции, которую, надеюсь, вы уже успели полюбить:

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

Первое, что делает обработчик — вызывает метод serialize() для элемента form. Это весьма полезный метод, который последовательно обрабатывает все элементы формы и создает строку, закодированную для передачи на сервер в качестве фрагмента URL-адреса. Для введенных мною значений метод serialize() генерирует следующую строку:

Я использую здесь метод serialize(), поскольку метод post() отправляет данные в закодированном для передачи в составе URL формате. Получив объект data, созданный на основе значений элементов input, мы вызываем метод post(), чтобы инициировать Ajax-запрос.

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

В этом примере получаемый от сервера ответ передается функции processServerResponse(). Сначала мы скрываем элементы div уровня ячеек, формирующие табличную компоновку страницы с использованием стилей CSS (они относятся к классу dcell), а затем отображаем те из них, которые соответствуют свойствам объекта JSON, полученного от сервера. Кроме того, мы используем шаблон данных для генерации разметки, отображающей общее количество выбранных единиц продукции. Это все можно было бы сделать с помощью клиента, но наша цель — научиться обрабатывать данные, возвращаемые POST-запросом Ajax. Результат показан на рисунке:

Теперь вы сами могли убедиться в том, насколько легко отправить данные формы на сервер (и, конечно же, насколько просто обработать ответ, особенно если он возвращается в формате JSON).

Указание ожидаемого типа данных

При использовании методов get() и post() библиотеке jQuery приходится определять тип данных, получаемых от сервера в ответ на запрос. Данными может быть все что угодно, начиная от HTML-кода и заканчивая файлами JavaScript. Для определения типа данных библиотека jQuery использует содержащуюся в ответе информацию, и в частности — заголовок Content-Type. Как правило, этого вполне достаточно, но иногда jQuery приходится оказывать небольшую помощь. Обычно необходимость в этом возникает из-за указания сервером неверного MIME-типа в ответе.

Можно изменить информацию, поставляемую сервером, и сообщить jQuery, какой тип данных ожидается, передавая методам get() и post() дополнительную информацию. Аргумент может принимать одно из следующих значений:

В примере ниже показано, как задать ожидаемый тип данных для метода post():

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

Ловушка при работе с Ajax

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

В этом сценарии определяется переменная elems, которая используется в функции обратного вызова Ajax для сохранения результата выполнения запроса к серверу. Полученные с сервера элементы добавляются в документ с помощью методов slice() и appendTo(). Если вы выполните этот пример, то увидите, что ни один из элементов не будет добавлен в документ, и вместо этого на консоли отобразится сообщение, конкретный текст которого зависит от типа браузера. Ниже приведено сообщение, отображаемое на консоли браузера Google Chrome:

Проблема заключается в том, что инструкции, содержащиеся внутри элемента script, выполняются не в том порядке, в котором они записаны. При написании этого кода предполагался следующий порядок выполнения инструкций:

Определяется переменная elems.

Получаемые с сервера данные присваиваются переменной elems.

Элементы извлекаются из переменной elems и добавляются в документ.

В действительности происходит следующее:

Определяется переменная elems.

Запускается асинхронный запрос к серверу.

Элементы извлекаются из переменной elems и добавляются в документ.

При этом в какой-то промежуточный момент времени вскоре после отправки браузером запроса происходит следующее:

В браузер поступают данные от сервера.

Данные обрабатываются и присваиваются переменной elems.


Причина появления сообщения об ошибке — вызов метода slice() для переменной в тот момент, когда она еще не содержит никаких элементов. Хуже всего то, что иногда этот код может работать правильно. Объясняется это тем, что Ajax-запрос выполняется настолько быстро, что к тому времени, когда начинается обработка переменной, в ней уже содержатся ожидаемые данные (обычно это наблюдается в тех случаях, когда данные кешируются браузером или когда между отправкой Ajax-запроса и попыткой обработки данных выполняются какие-либо сложные операции). Так что теперь, если ваш код будет вести себя подобным образом, вы уже знаете, что может быть причиной его необычного поведения.

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

Библиотека jQuery предоставляет три вспомогательных метода, которые делают работу с некоторыми типами данных более удобной. Некоторые из них мы рассмотрим далее.

Получение HTML-фрагментов

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

В этом сценарии мы вызываем метод load() для элемента, в который хотим вставить новые элементы, и передаем ему URL-адрес в качестве аргумента. Если запрос завершается успешно, а полученный от сервера ответ содержит действительный HTML-фрагмент, элементы вставляются в указанное место в документе, как показано на рисунке:

Вы видите, что все элементы из файла flowers.html добавлены в документ, как мы и хотели, но поскольку у них отсутствует атрибут class, то они не укладываются в табличную компоновку страницы, используемую в основном документе. Поэтому метод load() наиболее полезен в тех случаях, когда все элементы могут быть вставлены в одно место в документе без какой-либо дополнительной обработки.

Получение и выполнение сценариев

Метод getScript() загружает файл JavaScript, а затем выполняет содержащиеся в нем инструкции. Чтобы продемонстрировать работу этого метода, я создал файл myscript.js и сохранил его вместе с файлом test.html на своем веб-сервере. Содержимое этого файла представлено в примере ниже:

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

Самое важное, что необходимо знать при работе со сценариям, — между инициализацией Ajax-запроса и выполнением инструкций сценария состояние документа может измениться. В примере ниже приведен сценарий из основного документа, в котором по-прежнему используется метод getScript(), но при этом, еще до завершения Ajax-запроса, модифицируется дерево DOM:

Здесь мы вызываем метод getScript() для основной функции $() и передаем ему в качестве аргумента URL-адрес файла, который хотим использовать. Если сервер способен предоставить указанный файл и этот файл содержит действительный JavaScript-код, то последний будет выполнен.

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

Используя метод getScript(), можно быстро получать запрашиваемую информацию, не доставляя пользователям неудобств, вызванных необходимостью ожидания ответа. Уточню свою мысль. Я вовсе не предлагаю вам использовать этот метод для выполнения каких-либо действий скрытно от пользователя и говорю лишь о том, что следует отодвигать на второй план загрузку и выполнение вполне законной функциональности, если она представляет для пользователей меньшую ценность, чем затрачиваемое на ее ожидание время.

Цукерберг рекомендует:  Сайт - Нужна помощь

В данном примере после запуска Ajax-запроса с помощью метода getScript() из документа удаляется элемент row2, для чего используется метод remove(). Данный элемент используется в файле myscript.js для вставки новых элементов. Эти элементы отбрасываются незаметным для пользователя образом, поскольку в документе селектору #row2 ничто не соответствует. Итоговый результат представлен на рисунке:

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

Получение данных в формате JSON

Для загрузки данных JSON с сервера предназначен метод getJSON(). Возможно, это наименее полезный из всех трех вспомогательных методов, поскольку он не делает с данными ничего сверх того, что делает базовый метод get().

Примеры отправки AJAX JQuery

AJAX позволяет отправить и получить данные без перезагрузки страницы. Например, делать проверку форм, подгружать контент и т.д. А функции JQuery значительно упрощают работу.

Полное описание функции AJAX на jquery.com.

GET запрос

Запрос идет на index.php с параметром « text » и значением « Текст » через метод GET.
По сути это то же самое что перейти в браузере по адресу – http://site.com/index.php?text=Текст

В результате запроса index.php вернет строку «Данные приняты – Текст», которая будет выведена в сообщении alert.

Код можно сократить используя функцию $.get

Код файла index.php

GET запросы могут кэшироваться браузером или сервером, чтобы этого избежать нужно добавить в функцию параметр – cache: false .

POST запросы

Или сокращенная версия – функция $.post

Код файла index.php

POST запросы ни когда не кэшироваться.

Отправка формы через AJAX

При отправке формы применяется функция serialize() , подробнее на jquery.com.

Она обходит форму и собирает названия и заполненные пользователем значения полей и возвращает в виде массива – .

Технология AJAX

AJAX (аббревиатура от Asynchronous JavaScript and XML) – это технология взаимодействия с сервером без перезагрузки страницы. Поскольку не требуется каждый раз обновлять страницу целиком, повышается скорость работы с сайтом и удобство его использования.

История технологии

Многие технологии, которые используются в AJAX, известны еще с 1990-х годов. Так, в 1996 году в Internet Explorer 3 применялся HTML-элемент IFRAME, а в 1998 году компания Microsoft предложила подход Remote Scripting.

Непосредственно термин AJAX впервые был использован Джесси Джеймсом Гарретом 18 февраля 2005 года в статье «Ajax: A New Approach to Web Applications». Ее автор является одним из основателей и главой компании Adaptive Path. В своей статье он описал принцип разработки web-приложений, применяемый на тот момент в Google Maps и Gmail. По его словам, это стало «фундаментальным прорывом в возможностях, доступных в веб-приложениях».

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

По механизму работы страницы сразу можно сказать, что это AJAX сайт. Раньше пользователь должен был нажимать на кнопки и переходить по ссылкам для подтверждения своих действий. А теперь страница сама реагирует на внесение данных нужным образом. В результате время, затраченное на общение с сайтом, заметно сокращается. Пользователь общается с быстрореагирующим веб-приложением. Для его нормальной работы достаточно браузера, поддерживающего JavaScript, и подключения к Интернету.

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

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

Понять основной принцип работы AJAX помогает представленное ниже изображение:

В работе технологии можно выделить 4 основных этапа:

  1. Пользователь вызывает AJAX. Обычно это реализуется с помощью какой-либо кнопки, предлагающей получить больше информации.
  2. Система отправляет на сервер запрос и всевозможные данные. Например, может потребоваться загрузка определенного файла либо конкретных сведений из базы данных.
  3. Сервер получает ответ от базы данных и отправляет информацию в браузер.
  4. JavaScript получает ответ, расшифровывает его и выводит пользователю.

Для обмена данными на странице создается объект XMLHttpRequest, он будет выполнять функцию посредника между браузером и сервером. Запросы могут отправляться в одном двух типов – GET и POST. В первом случае обращение производится к документу на сервере, в роли аргумента ему передается URL сайта. Для предотвращения прерывания запроса можно воспользоваться функцией JavaScript Escape. Для больших объемов данных применяется функция POST.

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

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

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

Преимущества технологии AJAX

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

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

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

Широкий спектр возможностей. Использование AJAX не ограничивается формами. Например, при прохождении регистрации на некоторых сервисах пользователь вводит логин – и через мгновение ему выдается информация о том, свободен он или нет. Также при введении поискового запроса в Google после каждой буквы или слова предлагается несколько вариантов запроса. Это значительно повышает комфорт работы с сайтами.

Недостатки AJAX

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

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

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

Невозможность установить число обращений. Механизм динамической подгрузки контента заметно искажает данные статистики. Ведь в этом случае при перемещении пользователя по различным страницам не выполняется операция их перезагрузки. И обычный счетчик не регистрирует переход. Для крупных проектов такое искусственное занижение количества просмотров приводит к значительному падению доходов.

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

Индексирование AJAX поисковиками

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

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

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

  1. Перепишите ссылки в URL. После каждой # необходимо поставить восклицательный знак.
    Например, ссылку http://www.site.ru/#uslugi необходимо преобразовать в http://www.site.ru/#!uslugi.
  2. Для всех страниц AJAX версию HTML следует сделать доступной по определенному адресу. В нем установленное нами сочетание «#!» Необходимо заменить на «?_escaped_fragment_=». (В нашем примере http://www.site.ru/?_escaped_fragment_=uslugi).
  3. На странице AJAX нужно проставить тег: .
  4. Карта сайта в формате .xml ускорит индексацию его страниц.
  5. После индексации ресурса сравните его версию AJAX с сохраненной копией. Это позволит увидеть, все ли страницы проиндексированы ботами.

Влияние AJAX на ранжирование

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

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

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

Динамические страницы можно кэшировать и отображать их в качестве статических. Для вызова AJAX лучше воспользоваться классическим якорем, чем событием «onClick».

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

Ajax-запрос к серверу через jQuery

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

Запрос html-данных с помощью функции Load

Это самый простой ajax-запрос через jQuery с получением html-данных и их вставкой в dom-элемент с (содержимое элемента заменяется):


Более продвинутый вариант использования load:

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

Ajax-запросы функциями GET и POST

Эти функции осуществляют отправку ajax запроса http-методами get и post. Приведу пару примеров их использования.

Передача данных не обязательна, как и выполнение каких-либо действий после получения ответа от сервера, т.е. в этом случае, строчки 3 и 4-6 можно удалить при необходимости и таким образом еще сократить код.

Тип получаемых от сервера данных можно указать, добавив dataType (см.ниже) — по-умолчанию определяется автоматически.

Использование post аналогично, но в следующем примере использую вызов функции после получения ответа от сервера.

На самом деле, функции get и post являются сокращенными вариантами функции ajax, которую рассмотрю ниже.

Получение json-данных с помощью getJSON

getJSON — укороченный вариант ajax-запроса методом GET и получением данных в виде json. Способ удобен, например, для получения какого-то массива с данными и последующей работы с ним.

На стороне сервера программа формирует массив и преобразовывает его в json-строку, например, так:

Точно так же можно передать с сервера и объекты stdClass, преобразовав их в json-строку.

Простой ajax-запрос через jQuery с помощью функции AJAX

Теперь приведу пример простого get запроса функцией ajax и получением html-данных.

Запрос к серверу происходит get-методом, т.к. параметр, отвечающий за тип запроса, type по-умолчанию равен GET.

Более сложный пример ajax-запроса через jQuery

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

Кнопка отправки данных:

В приведенном примере при нажатии на кнопку button, сначала меняется состояние кнопки (текст на ней меняется на «Отправка. » и она становится не активной), что делается при помощи параметра beforeSend. Затем происходит отправка запроса с передачей нужных данных. После того, как получен ответ от сервера состояние кнопки возвращается в прежнее (текст меняется на «Отправить», становится активной). Ответ получается в виде json-данных.

Коротко опишу параметры отправки ajax-запроса, которые чаще всего могут пригодиться:

url Адрес отправки ajax-запроса
type Способ отправки запроса GET или POST
data Отправляемые серверу данные. Может быть строка с параметрами и их значениями в формате par1=val1&par2=val2&. объект jQuery, например, $(‘input[type=»text»]’) или другие данные.
dataType Тип получаемых от сервера данных. Может быть html, json, text, script и xml.
cache Кэширование браузером запроса (false — не кэшировать).
async Асинхронное выполнение запроса, т.е. программа продолжает выполняться не дожидаясь ответа сервера. Если указать false, то запрос будет выполнен синхронно, при этом страница не будет ни на что реагировать, пока не будет получен ответ от сервера.
processData Преобразование отправляемых данных в url-формат. Если нужно чтобы данные не преобразовывались, установить в false. Например, при отправке изображения на сервер или xml-данных.
contentType Тип передаваемых данных, по умолчанию «application/x-www-form-urlencoded; charset=UTF-8». Если указать false, то в заголовке не будет передаваться тип, что может быть необходимо, например, при отправке изображения на сервер.
beforeSend Функция, выполняемая перед отправкой ajax-запроса.
complete Функция, выполняемая после получения ответа от сервера (любого, успешного или нет).
success Функция, выполняемая при удачном выполнении запроса.
error Функция, выполняемая в случае ошибки.

Ниже приведу еще несколько примеров использования ajax-запросов.

Отправка формы со всеми данными ajax-запросом через jQuery

Примерный код html-формы:

Для того чтобы страница не перезагружалась при нажатии на кнопку «submit», сначала отменяем стандартые действия браузера использовав e.preventDefaults() .

В параметре data мы передаем все поля формы использовав $(this).serialize() — эта функция преобразует все input-ы и select-ы в строку, пригодную для отправки на сервер.

Так же, здесь использован параметр async: false , чтобы пока форма не отправится на сервер больше ничего нельзя было нажать или сделать.

Отправка изображения или файла ajax-запросом через jQuery

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

html-код будет такой:

Суть идеи в том, что поверх кнопки выводится стандартный input для выбора файла, но он полностью прозрачен и имеет такие же размеры как кнопка. Таким образом, пользователь видит кнопку button, но когда наводит на нее курсор, фактически наводит на input. Соответственно, когда он нажимает на кнопку, на самом деле нажимается input выбора файла. Для того, чтобы не мигал курсор после выбора файла, размер шрифта задан 0px.

Теперь javascript код отправки файла на сервер с отображением прогресса:

При загрузке файла на сервер в кнопке будет показываться сколько % уже передано на сервер. После завершения загрузки название кнопки возвращается как было, а значение input-а с файлом устанавливается пустым, чтобы можно было снова выбирать новый файл.

Пример серверной части на php (по просьбе Евгения):

Информация о загруженном изображении будет содержаться в $_FILES[‘upload’] , т.к. скриптом файл добавлялся так: form.append(‘upload’, files[0]); Соответственно, всё что требуется от php-программы — это проверить что файл соответствует ожидаемым параметрам, перенести файл в нужную папку (в примере в папку files) под нужным именем (в примере newname_image) и вернуть в браузер ответ, который в моем примере просто выводится пользователю командой alert(message);

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

Ajax-запрос

Материал из JQuery

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

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

Содержание

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Начиная с 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 будет доступен в текстовом виде. Если он содержит скрипты в тегах

Освоение Ajax: Часть 2. Выполнение асинхронных запросов с JavaScript и Ajax

Использование XMLHttpRequest для Web-запросов

Большинство Web-приложений используют модель запрос/ответ, в которой получают от сервера HTML-страницу полностью. В результате получаем работу по типу "вперед и назад", обычно состоящую из нажатия кнопки, ожидания сервера, нажатия другой кнопки и опять ожидания сервера. При помощи Ajax и объекта XMLHttpRequest вы можете использовать модель запрос/ответ, которая никогда не оставляет пользователей в ожидании ответа сервера. В данной статье Брэт Маклафлин расскажет о создании экземпляров XMLHttpRequest кросс-браузерным способом, построении и передаче запросов и реакции сервера.

Брэт Маклафлин, автор и редактор, O'Reilly Media Inc.

Брэт Маклафлин (Brett McLaughlin) работает с компьютерами со времен Logo (помните маленький треугольник?). За последние несколько лет он стал одним из наиболее известных авторов и программистов сообщества по технологиям Java и XML. Он работал в Nextel Communications над реализацией сложных корпоративных систем, в Lutris Technologies, фактически, над созданием сервера приложений, а с недавних пор работает в O'Reilly Media, Inc., где продолжает писать и редактировать книги по данной тематике. В готовящейся Брэтом вместе с популярными авторами Эриком и Бет Фриманами книге Быстрый штурм Ajax использован общепризнанный и передовой подход к Ajax по методу Head First. Его недавняя книга "Java 1.5 Tiger: Заметки разработчика", является первой доступной книгой по новейшей технологии Java, а его классическая "Java и XML" остается одной из наиболее авторитетных работ по использованию технологий XML в языке программирования Java.

  • Содержание

В первой статье этой серии (ссылка приведена в разделе Ресурсы) вы познакомились с Ajax-приложениями и некоторыми основными концепциями, присущими Ajax-приложениям. В центре всего присутствует много технологий, о которых вы, вероятно, уже знаете: JavaScript, HTML, XHTML, немного динамического HTML и даже DOM (Document Object Model). В данной статье я спущусь с высоты 10000 футов и остановлюсь на конкретных деталях Ajax.

Вы начнете с самого фундаментального и базового из всех Ajax-объектов и программных подходов - объекта XMLHttpRequest . Он, фактически, является единственной общей нитью для всех Ajax-приложений, и (как можно ожидать) вы захотите тщательно изучить его для повышения вашей квалификации программиста до максимально возможных пределов. На самом деле когда-нибудь обнаружится, что для правильного использования XMLHttpRequest вы явно не хотите использовать XMLHttpRequest . Так зачем же все это, черт возьми?

Web 2.0 с первого взгляда

Прежде всего, я сделаю последний маленький обзор перед погружением в исходный код, чтобы убедиться, что вы совершенно ясно представляете эту идею с Web 2.0. Когда вы слышите термин Web 2.0, то должны прежде всего спросить: "А что такое Web 1.0?" Хотя вы вряд ли слышали про Web 1.0, этот термин означает ссылку на традиционный Web, в котором используется совершенно четкая модель запроса и ответа. Например, откройте сайт Amazon.com и нажмите кнопку или введите строку поиска. Этот запрос содержит значительно больше, чем просто список книг; это фактически другая полная HTML-страница. В результате вы, вероятно, увидите некоторое мигание и мерцание во время перерисовки Web-браузером этой новой HTML-страницы. На самом деле, можно ясно увидеть запрос и ответ, разграниченные каждой новой страницей, которая будет отображена.

Цукерберг рекомендует:  Почувствуй себя богом, или Моделирование жизни на Java. Часть III

Web 2.0 обходится без этой очень заметной процедуры "вперед и назад" (в значительной степени). В качестве примера посетите сайт Google Maps или Flickr (ссылки на оба этих Web 2.0 сайта, работающих на Ajax, приведены в разделе Ресурсы). На Google Maps, например, вы можете повернуть карту, приблизить или удалить ее с очень небольшой перерисовкой. Естественно, запросы и ответы выполняются и здесь, но это происходит в фоновом режиме. С точки зрения пользователя, впечатление очень хорошее; есть такое чувство, что работаешь с настольным приложением. Это новое чувство (и парадигма) и имеются в виду, когда идет речь о Web 2.0.


Единственное, о чем вы должны позаботиться, – как сделать возможными эти новые взаимодействия. Очевидно, вы все равно должны выполнять запросы и получать ответы, но эта перерисовка HTML для каждой операции запрос/ответ и дает ощущение медленного, тяжеловесного Web-интерфейса. Поэтому понятно, что необходим новый подход, позволяющий выполнять запросы и получать ответы, которые содержат только необходимые данные вместо целой HTML-страницы. Единственный момент, когда вы хотите получить полностью новую HTML-страницу, - это… ммм. когда вы хотите, чтобы пользователь увидел новую страницу.

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

Знакомство с XMLHttpRequest

Для того чтобы весь этот блеск и чудо произошли на самом деле, вы должны тесно познакомиться с объектом JavaScript, называемым XMLHttpRequest . Этот маленький объект – ключ к Web 2.0, Ajax и, в большой степени, ко всему прочему, что вы узнаете в этом разделе в течение последующих нескольких месяцев. Чтобы сделать действительно быстрый обзор, остановимся всего лишь на нескольких методах и свойствах, которые вы будете использовать в этом объекте:

  • open() : Устанавливает новый запрос к серверу;
  • send() : Передает запрос серверу;
  • abort() : Прекращает текущий запрос;
  • readyState : Хранит текущее состояние готовности HTML;
  • responseText : Текст, который сервер передал назад как ответ на запрос.

Не беспокойтесь, если вы не все понимаете из этого (или вообще ничего по этой теме) – вы изучите каждый метод и свойство в следующих нескольких статьях. Что вы должны вынести из этого – четкое представление о том, что делать с XMLHttpRequest . Обратите внимание, что каждый из этих методов и свойств относится к передаче запроса и работает с ответом. На самом деле, если вы видели все методы и свойства XMLHttpRequest , все они будут иметь отношение к этой очень простой модели запрос/ответ. Из этого понятно, что вы не будете изучать новый изумительный GUI-объект или определенного рода сверхсекретный подход к созданию взаимодействия с пользователем; вы будете работать с простыми запросами и простыми ответами. Это, возможно, звучит не очень захватывающе, но осторожное использование этого единственного объекта может полностью изменить ваши приложения.

Простота нового

Во-первых, вы должны создать новую переменную и присвоить ей экземпляр объекта XMLHttpRequest . Это довольно просто в JavaScript; вы используете ключевое слово new с именем объекта, как показано в листинге 1.

Листинг 1. Создание нового объекта XMLHttpRequest

Это совсем не тяжело, не правда ли? Помните, что JavaScript не требует типизации своей переменной, поэтому вам не нужно ничего из того, что вы видите в листинге 2 (возможно, так бы вы создавали этот объект на Java).

Листинг 2. Псевдо-код Java для создания XMLHttpRequest

Итак, вы создаете переменную в JavaScript при помощи var , даете ей имя (например, "request"), и присваиваете ей новый экземпляр XMLHttpRequest . На данном этапе вы готовы использовать объект в ваших функциях.

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

В реальной жизни вещи могут портиться, и этот код не обеспечивает никакой обработки ошибок. Несколько лучший способ – создать этот объект и дать ему грациозно потерпеть неудачу, если что-либо пойдет не так. Например, многие старые браузеры (верите или нет, люди все еще используют старые версии Netscape Navigator) не поддерживают XMLHttpRequest , и вам нужно предупредить таких пользователей, что что-то не получилось. В листинге 3 показано, как можно создать этот объект так, что если что-то поломается, он покажет предупреждение на JavaScript.

Листинг 3. Создание XMLHttpRequest с некоторыми способностями обработки ошибок

Убедитесь, что вы понимаете каждый из следующих шагов:

  1. Создайте новую переменную с именем request и присвойте ей значение false. Вы будете использовать false как условие, означающее, что объект XMLHttpRequest еще не был создан.
  2. Добавьте блок try/catch:
    1. Попробуйте создать объект XMLHttpRequest .
    2. Если это не удалось ( catch (failed) ), удостоверьтесь, что request все еще равен false.
  3. Проверьте и узнайте, равно ли false значение request (если все прошло нормально, этого не случится).
  4. Если была проблема (и request равна false), используйте предупреждение JavaScript для сообщения пользователю о возникновении проблемы.

Это довольно просто; у большинства JavaScript- и Web-разработчиков больше времени уходит на чтение и написание, чем на понимание. Теперь у вас есть защищенный от ошибок код, создающий объект XMLHttpRequest и даже предупреждающий вас о том, что что-то прошло не так.

Работа с Microsoft

Это все выглядит довольно хорошо. по крайней мере, пока вы не попробуете этот код в Internet Explorer. Если вы это сделаете, то получите что-то, выглядящее так же ужасно, как на рисунке 1.

Рисунок 1. Internet Explorer отображает ошибку

Microsoft играет по правилам?

Много было написано об Ajax и увеличивающемся интересе Microsoft к присутствию в этой области. Действительно ожидается, что новейшая версия Internet Explorer (версия 7.0, намеченная к выходу в 2006) будет поддерживать XMLHttpRequest напрямую, позволяя вам использовать ключевое слово new вместо всего кода создания Msxml2.XMLHTTP . Но не слишком обольщайтесь; вам все равно необходимо поддерживать старые браузеры, поэтому кросс-браузерный код уйдет со сцены еще не скоро.

Понятно, что что-то не работает; Internet Explorer – это тяжелый устаревший браузер, но около 70% пользователей его используют. Другими словами, вы не сделаете много в Web-мире, если не будете поддерживать Microsoft и Internet Explorer! Поэтому нужен другой метод работы с браузерами Microsoft.

Оказывается, что Microsoft поддерживает Ajax, но называет свою версию XMLHttpRequest по-другому. Вернее он называет этот объект несколькими разными именами. Если вы используете более новую версию Internet Explorer, то должны использовать объект Msxml2.XMLHTTP ; некоторые старые версии Internet Explorer используют Microsoft.XMLHTTP . Вы должны поддерживать оба типа объектов (без потери уже имеющейся поддержки браузеров не от Microsoft). В листинге 4 приведен уже знакомый код с добавленной поддержкой Microsoft.

Листинг 4. Добавление поддержки для браузеров Microsoft

Легко затеряться в фигурных скобках, поэтому рассмотрим поэтапно все действия:

  1. Создайте новую переменную с именем request и присвойте ей значение false. Вы будете использовать false как условие, означающее, что объект XMLHttpRequest еще не был создан.
  2. Добавьте блок try/catch:
    1. Попробуйте создать объект XMLHttpRequest .
    2. Если это не удалось ( catch (trymicrosoft) ):
      1. Попробуйте создать совместимый с Microsoft объект, используя более новые версии Microsoft ( Msxml2.XMLHTTP ).
      2. Если это не удалось ( catch (othermicrosoft) ), попробуйте создать совместимый с Microsoft объект, используя старые версии Microsoft ( Microsoft.XMLHTTP ).
    3. Если это не удалось ( catch (failed) ), удостоверьтесь, что request все еще равен false.
  3. Проверьте и узнайте, равно ли еще false значение request (если все прошло нормально, этого не случится).
  4. Если была проблема (и request равна false), используйте предупреждение JavaScript для сообщения пользователю о возникновении проблемы.

Выполните эти изменения в своем коде и попробуйте снова выполнить его в Internet Explorer; Вы должны увидеть созданную вами форму (без сообщения об ошибке). В моем случае результат выглядел так, как показано на рисунке 2.

Рисунок 2. Internet Explorer работает нормально

Статика против динамики

Взгляните снова на листинги 1, 3 и 4 и обратите внимание, что весь этот код непосредственно вложен внутри тегов сценария. Когда JavaScript закодирован подобным образом и не размещен внутри тела метода или функции, он называется статическим JavaScript. Это означает, что код выполняется в какой-то момент времени до того, как страница отобразится пользователю (из спецификации не ясно с точностью 100%, когда этот код выполняется, и браузеры поступают по-разному; но все же есть гарантия, что код выполняется до того, как пользователи смогут взаимодействовать с вашей страницей). Обычно большинство Ajax-программистов именно так и создают объект XMLHttpRequest .

Как было сказано, вы определенно можете поместить этот код в метод в соответствии с листингом 5.

Листинг 5. Перемещение кода создания XMLHttpRequest в метод

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

Листинг 6. Использование метода для создания XMLHttpRequest

Единственное замечание по поводу этого кода (и причина того, почему многие Ajax-программисты не используют такой подход) – он задерживает вывод сообщения об ошибке. Представьте, что у вас имеется сложная форма с 10 или 15 полями, рамками выбора вариантов и т.п., и вы активизируете какой-либо Ajax-код при вводе пользователем текста в поле 14 (внизу формы). Активизируется getCustomerInfo() , который пытается создать объект XMLHttpRequest , и (для данного примера) терпит неудачу. Пользователю выводится предупреждение, сообщающее о том (во многих словах), что он не может использовать это приложение. Но пользователь уже потратил время для заполнения формы! Это довольно неприятно, и эта неприятность не входит в число тех вещей, из-за которых пользователь захотел бы вернуться на ваш сайт.

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

Передача запросов с XMLHttpRequest

После того как вы создали объект request, можете начать цикл запрос/ответ. Вспомните, что единственной целью объекта XMLHttpRequest является предоставление вам возможности посылать запросы и получать ответы. Все остальное (изменение пользовательского интерфейса, замена изображений, даже интерпретация переданных сервером данных) – это работа JavaScript, CSS или другого кода на ваших страницах. С готовым к использованию XMLHttpRequest вы можете сейчас послать запрос серверу.

Добро пожаловать в "песочницу"

Ajax имеет модель безопасности по типу "песочницы". В результате ваш Ajax-код (и, в частности, объект XMLHttpRequest ) может посылать запросы только тому домену, на котором выполняется. Вы подробнее узнаете о безопасности и Ajax в следующей статье, а теперь просто запомните, что код, выполняющийся на вашем локальном компьютере, может выполнять запросы только к серверным сценариям на вашем локальном компьютере. Если ваш Ajax-код работает на www.breakneckpizza.com, он должен посылать запросы к сценариям, работающим на www.breakneckpizza.com.

Установка URL сервера

Первое, что вам необходимо определить – это URL сервера для подключения. Это не является специфичным для Ajax (очевидно вы должны знать, как составить URL), но это существенно для выполнения соединения. В большинстве приложений вы будете составлять этот URL из некоторого набора статических данных в комбинации с данными из формы, с которой работают ваши пользователи. Например, в листинге 7 показан код JavaScript, который собирает значение поля с телефонным номером и составляет URL, используя эти данные.

Листинг 7. Создание URL-запроса

Ничто не должно быть здесь не понятным для вас. Сначала код создает новую переменную phone и присваивает ей значение поля формы, имеющего ID "phone". В листинге 8 приведен XHTML для этой конкретной формы, в которой вы можете увидеть поле field и его атрибут id .

Листинг 8. Форма "Break Neck Pizza"

Обратите также внимание, что когда пользователи вводят телефонный номер или изменяют номер, вызывается метод getCustomerInfo() , приведенный в листинге 8. Затем этот метод собирает этот номер и использует его для составления строки URL, сохраняемой в переменной url . Помните: поскольку Ajax-код выполняется в "песочнице" и может соединяться только с тем же самым доменом, вам фактически не нужно указывать домен в URL. В данном примере имя сценария - /cgi-local/lookupCustomer.php . Наконец, номер телефона добавляется к этому сценарию как параметр GET: "phone=" + escape(phone) .

Для тех, кто никогда прежде не видел метод escape() , я поясню - он используется для перевода в другое представление любого символа, который не может быть передан корректно в виде простого текста. Например, все пробелы в номере телефона преобразуются в символы %20 , что дает возможность передачи этих символов в URL.

Вы можете добавить столько параметров, сколько нужно. Например, если вы хотите добавить еще один параметр, просто добавьте его к URL и разделите параметры символом амперсанда ( & ) [первый параметр отделяется от имени сценария знаком вопроса ( ? )].

Открытие запроса

Открывает ли open()?

Internet-разработчики не пришли к согласию насчет того, что точно делает метод open() . Чего он действительно не делает, так это не открывает запрос. Если бы вы проследили за сетью и передачей данных между вашей XHTML/Ajax-страницей и сценарием, с которым она связана, то не увидели бы никакого трафика при вызове метода open() . Непонятно почему было выбрано именно это имя, но ясно, что это не лучший выбор.

Имея URL, вы можете сконфигурировать запрос. Это делается при помощи метода open() вашего объекта XMLHttpRequest . Этот метод принимает пять параметров:

  • request-type: Тип передаваемого запроса. Обычными значениями являются GET или POST , но вы можете также передать HEAD -запросы.
  • url: URL для соединения.
  • asynch: True, если вы хотите, чтобы запрос был асинхронным, и false, если он должен быть синхронным. Этот параметр необязателен и по умолчанию равен true.
  • username: Если требуется аутентификация, то здесь вы можете указать имя пользователя. Это необязательный параметр и он не имеет значения по умолчанию.
  • password: Если требуется аутентификация, здесь вы можете указать пароль. Это необязательный параметр и он не имеет значения по умолчанию.

Обычно вы будете использовать три первых параметра. На самом деле, даже если вы хотите асинхронный запрос, желательно указывать "true" в качестве третьего параметра. Это значение по умолчанию, но это приятная мелочь для самодокументирования. Всегда видно, асинхронный запрос или нет.

Объедините все это вместе, и у вас, скорее всего, получится примерно такая строка, какая показана в листинге 9.

Листинг 9. Открытие запроса

Как только вы вычислили URL, все становится тривиальным. Для большинства запросов использования GET достаточно (в будущих статьях вы увидите ситуации, в которых, возможно, захотите использовать POST ); это все, что вам нужно для использования open() .

Головоломка по асинхронии

В последующей статье этой серии я потрачу значительную часть времени на написание и использование асинхронного кода, но вы должны иметь представление о том, почему последний параметр в open() настолько важен. В обычной модели запрос/ответ (здесь думайте о Web 1.0) клиент (ваш браузер или код, выполняющийся на вашей локальной машине) посылает запрос серверу. Этот запрос является синхронным; другими словами, клиент ждет ответа от сервера. Пока клиент ждет, вы обычно получаете одну из нескольких форм уведомления о том, что вы ждете:

  • Песочные часы (главным образом в Windows).
  • Крутящийся мяч (обычно на Mac-компьютерах).
  • Приложение замирает и иногда меняется курсор.

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


Асинхронный запрос не ждет ответа от сервера. Вы посылаете запрос, и ваше приложение продолжает работу. Пользователи могут вводить данные в Web-форму, нажимать другие кнопки, даже уйти с формы. Нет крутящегося мяча или вращающихся песочных часов, и нет больших замираний приложения. Сервер молча отвечает на запрос, и когда завершается передача ответа, он дает знать об этом инициатору запроса (способами, о которых вы вскоре узнаете). В результате мы имеем приложение, которое не выглядит неуклюжим или медленным, а, наоборот, чувствительным, интерактивным и быстрым. Это только один компонент Web 2.0, но это очень важный компонент. Любые прекрасные GUI-компоненты и парадигмы Web-дизайна не могут преодолеть медленную, синхронную модель запрос/ответ.

Передача запроса

После настройки запроса с использованием open() вы готовы к передаче запроса. К счастью, метод для передачи запроса назван более правильно, чем open() ; его просто назвали send() .

send() принимает только один параметр – содержимое для передачи. Но прежде чем вы серьезно задумаетесь об этом, вспомните, что вы уже передали данные в самом URL:

И хотя вы можете передать данные с использованием send() , вы можете также передать их через сам URL. В действительности в GET -запросах (которые будут составлять до 80% типичного использования Ajax) намного легче передавать данные в URL. Когда вы начинаете передавать защищенную информацию или XML, нужно рассмотреть передачу содержимого через send() (я рассмотрю защищенные данные и обмен XML-сообщениями в последующей статье этой серии). Если вам не надо передавать данные через send() , установите аргумент в значение null . Для передачи запроса в примере, используемом в данной статье, это именно то, что нам нужно (см. листинг 10).

Листинг 10. Передача запроса

Указание метода обратного вызова

До сих пор вы сделали очень немного такого, что являлось бы чем-то новым, революционным или асинхронным. Маленькое ключевое слово "true" в методе open() устанавливает асинхронный запрос. На стороне сервера код пишется на Java-сервлетах и JSP, PHP или Perl. Так в чем же большой секрет Ajax или Web 2.0? Секрет вертится вокруг простого свойства XMLHttpRequest с названием onreadystatechange .

Прежде всего, вы должны понимать процесс, который вы создали в этом коде (пересмотрите листинг 10 при необходимости). Запрос настраивается и затем передается. Кроме того, поскольку это асинхронный процесс, JavaScript-метод ( getCustomerInfo() в примере) не будет ожидать сервер. Поэтому код будет продолжать выполняться; в данном случае это означает, что произойдет выход из метода и управление вернется в форму. Пользователь может продолжить ввод информации, и приложение не будет ожидать сервер.

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

Ссылка на функцию в JavaScript

JavaScript является слабо типизированным языком, и в переменной вы можете ссылаться почти на все, что угодно. То есть, если вы объявили функцию с названием updatePage() , JavaScript также рассматривает имя этой функции как переменную. Другими словами, вы можете ссылаться на функцию в вашем коде как на переменную с названием updatePage .

Здесь выходит на сцену свойство onreadystatechange . Это свойство позволяет вам указать метод обратного вызова (callback). Метод обратного вызова позволяет серверу (можете догадаться?) выполнить обратный вызов в коде вашей Web-страницы. Это добавляет в сервер уровень контроля; когда сервер завершает обработку запроса, он ищет объект XMLHttpRequest и, в частности, его свойство onreadystatechange . Затем активизируется любой метод, указанный в этом свойстве. Он называется методом обратного вызова, потому что сервер инициирует вызов в обратном направлении (в Web-странице) независимо от того, что происходит в самой Web-странице. Например, он может вызвать этот метод тогда, когда пользователь сидит в кресле, не трогая клавиатуру; однако, он может вызвать этот метод и тогда, когда пользователь вводит информацию, перемещает мышку, выполняет скроллинг страницы, нажимает кнопку. не важно, что делает пользователь.

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

Листинг 11. Установка метода обратного вызова

Обратите особое внимание на то, где в коде устанавливается это свойство – перед вызовом send() . Вы должны установить это свойство перед передачей запроса, поэтому сервер может просмотреть его после завершения обработки запроса. Все, что нам осталось – написать updatePage() , что и рассматривается в последнем разделе этой статьи.

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

Вы передали запрос, ваш пользователь с удовольствием работает с Web-формой (в то время, когда сервер обрабатывает запрос), и теперь сервер завершает обработку запроса. Сервер просматривает свойство onreadystatechange и определяет, какой вызвать метод. После этого вы можете представлять свое приложение как любое другое приложение, асинхронное или нет. Другими словами, вы не должны принимать каких-либо специальных действий по написанию методов, реагирующих на сервер; просто измените форму, перенаправьте пользователя на другой URL, или сделайте все что хотите, реагируя на переданный из сервера ответ. В этом разделе мы остановимся на реакции на ответ от сервера и выполним обычное действие – изменим на лету часть формы, которую видит пользователь.

Обратные вызовы и Ajax

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

Листинг 12. Код метода обратного вызова

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

Рисунок 3. Ajax-код вывода всплывающего предупреждения

В зависимости от вашего браузера вы получите два, три или даже четыре предупреждения, прежде чем форма прекратит отображать всплывающее окно. Что же происходит? Вы не приняли во внимание состояние готовности HTTP, важного компонента цикла запрос/ответ.

Цукерберг рекомендует:  Как основатель Lamoda занялся виртуальной реальностью

Состояния готовности HTTP

Раньше я говорил, что сервер, закончив обработку запроса, ищет, какой метод вызвать в свойстве onreadystatechange объекта XMLHttpRequest . Это правда, но это не вся правда. На самом деле он вызывает этот метод каждый раз, когда меняется состояние готовности HTTP. Что это значит? Хорошо, вы сначала узнаете об этих состояниях.

Состояние готовности HTTP отображает состояние или статус запроса. Оно используется для определения того, начат ли запрос, принимается ли ответ, или завершен ли цикл запрос/ответ. Это состояние помогает также при определении того, можно ли читать текст или данные, которые сервер мог предоставить в ответе. Вы должны знать о пяти состояниях готовности в ваших Ajax-приложениях:

  • : Запрос не инициализирован (перед вызовом open() ).
  • 1: Запрос инициализирован, но не был передан (перед вызовом send() ).
  • 2: Запрос был передан и обрабатывается (на данном этапе вы можете обычно получить заголовки содержимого из ответа).
  • 3: Запрос обрабатывается; часто в ответе доступны некоторые частичные данные, но сервер не закончил свой ответ.
  • 4: Ответ завершен; вы можете получить ответ сервера и использовать его.

Как и почти все кросс-браузерные проблемы, эти состояния готовности используются несколько непоследовательно. Вы могли бы ожидать, что состояния всегда изменяются от 0 к 1, от 1 к 2, от 2 к 3, от 3 к 4, но на практике это редкий случай. Некоторые браузеры никогда не выдают 0 или 1, а сразу перепрыгивают к 2, затем к 3 и 4. Другие браузеры выдают все состояния. Но некоторые выдают состояние 1 несколько раз. Как вы видели в последнем разделе, сервер вызывал updatePage() несколько раз, и каждый вызов приводил к появлению всплывающего окна предупреждения – наверное, это не то, чего вы хотели!

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

Листинг 13. Проверка состояния готовности

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

Коды состояния HTTP

Несмотря на явный успех кода в листинге 13, есть одна проблема – что если сервер ответил на ваш запрос и завершил обработку, но возвращает ошибку? Вспомните, ваш серверный код не знает, был ли вызван он Ajax-приложением, JSP-страницей, обычной HTML-формой или любым другим типом кода; он имеет только традиционные Web-методы оповещения. И в Web-мире HTTP-коды могут иметь дело с различными вещами, которые могут возникнуть в запросе.

Например, вы составили запрос к URL, ввели URL неправильно и получили код ошибки 404, указывающий, что страница отсутствует. Это один из многих кодов состояния, которые могут получать HTTP-запросы (ссылка на полный список кодов состояния приведен в разделе Ресурсы). Также распространенными являются коды 403 и 401, указывающие на то, что запрашиваются защищенные или запрещенные данные. В каждом из этих случаев есть коды, которые приходят в ответе. Другими словами, сервер выполнил запрос (означает, что состояние готовности HTTP равно 4), но, возможно, не возвращает данные, ожидаемые клиентом.

То есть, кроме состояния готовности вы должны также проверять HTTP-состояние. Вам подходит код состояния 200, просто означающий, что все в порядке. С состоянием готовности 4 и кодом состояния 200 вы готовы обработать серверные данные, и эти данные должны быть теми, которые вы запрашивали (и нет ошибок или другой проблемной информации). Добавьте еще одну проверку в ваш метод обратного вызова, как показано в листинге 14.

Листинг 14. Проверка кода состояния HTTP

Для более устойчивой обработки ошибок (с минимальным усложнением кода) вы можете добавить проверку или две для других кодов состояния; Посмотрите на модифицированную версию updatePage() в листинге 15.

Листинг 15. Добавление некоторой обработки ошибок

Теперь измените URL в getCustomerInfo() в несуществующий URL и посмотрите, что произойдет. Вы должны увидеть предупреждение, говорящее о том, что запрошенный вами URL не существует – отлично! Очень трудоемко обрабатывать все ошибки, но это простое изменение решит 80 % проблем, которые могут возникнуть в обычном Web-приложении.

Чтение текста ответа

Теперь, когда вы убеждены, что запрос полностью обработан (через состояние готовности) и сервер вернул нормальный положительный ответ (через код состояния), можно, наконец, заняться данными, переданными от сервера. Они удобно сохранены в свойстве responseText объекта XMLHttpRequest .

Подробности о тексте в responseText , в терминах формата или длины, преднамеренно оставлены неопределенными. Это позволяет серверу установить этот текст виртуально во все что угодно. Например, один сценарий может возвратить разделенные запятыми значения, другой – разделенные вертикальной чертой значения (символ " | "), а третий может возвратить одну длинную строку текста. Это решает сервер.

В примере этой статьи сервер возвращает последний заказ клиента и его адрес, разделенные символом вертикальной черты. Заказ и адрес используются для установки элементов формы; в листинге 16 приведен код, обновляющий дисплей.

Листинг 16. Работа с ответом сервера

Сначала извлекается responseText и разделяется на части по символам вертикальной строки (" | ") при помощи метода JavaScript split() . Получившийся массив значений присваивается массиву response . Первое значение (последний заказ клиента) находится в response[0] и устанавливается как значение поля с ID "order." Второе значение массива, response[1] , является адресом клиента и требует несколько большей обработки. Поскольку строки в адресе разделены обычными разделителями строк (символ " \n "), нужно заменить их XHTML-разделителями строк
. Это выполняется при помощи функции replace() с регулярным выражением. Наконец, модифицированный текст устанавливается как inner HTML элемента div в форме HTML. В результате этого форма неожиданно обновляется пользовательской информацией, как показано на рисунке 4.

Рисунок 4. Форма Break Neck после извлечения пользовательских данных

Перед заключением рассмотрим еще одно важное свойство XMLHttpRequest - responseXML . Это свойство содержит (догадались?) XML-ответ в случае, если сервер решил ответить в XML-формате. Работа с XML ответом существенно отличается от работы с обычным неформатированным текстом и включает работу с синтаксическим анализатором, Document Object Model (DOM) и некоторые другие соображения. Более подробно о работе с XML вы узнаете из будущей статьи. Пока же, поскольку responseXML обычно рассматривается при обсуждении responseText , мы просто упомянем его. Для многих простых Ajax-приложений responseText – это все что вам нужно, но вскоре вы научитесь работать также и с XML в Ajax-приложениях.

В заключение

Вы, возможно, уже немножко устали от XMLHttpRequest – я редко читаю целую статью об одном объекте, особенно если он простой. Однако вы будете использовать этот объект снова и снова в каждой странице и приложении, которое пишете с использованием Ajax. По правде говоря, осталось еще кое-что, что нужно сказать об XMLHttpRequest . В последующих статьях вы научитесь использовать в ваших запросах POST в дополнение к GET , устанавливать и читать заголовки содержимого в ваших запросах и ответах сервера; вы научитесь кодировать ваши запросы и даже работать с XML в вашей модели запрос/ответ.

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

Поэтому не игнорируйте эти детали и не просматривайте их беглым взглядом; когда ваша инструментальная программа создаст ошибку, вы не застрянете на ней, почесывая голову и посылая электронные письма в службу поддержки. Со знанием методов непосредственного использования XMLHttpRequest вы обнаружите, насколько легко отлаживать и исправлять даже самые странные ошибки. Инструментарий хорош тогда, когда вы можете полностью рассчитывать на него в решении всех ваших проблем.

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

В следующей статье вы еще глубже проникнете в этот объект, исследуя некоторые из его хитрых свойств (например, responseXML ), а также узнаете, как использовать POST -запросы и передавать данные в нескольких различных форматах. Итак, начнем кодирование.

Знакомство с AJAX для Front-End дизайнеров. Основы AJAX

Дата публикации: 2020-02-15

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

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

Что такое AJAX?

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

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

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

JavaScript. Быстрый старт

Изучите основы JavaScript на практическом примере по созданию веб-приложения

«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.

JavaScript. Быстрый старт

Изучите основы JavaScript на практическом примере по созданию веб-приложения

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

Ajax-запрос к серверу через jQuery

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

Запрос html-данных с помощью функции Load

Это самый простой ajax-запрос через jQuery с получением html-данных и их вставкой в dom-элемент с (содержимое элемента заменяется):

Более продвинутый вариант использования load:

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

Ajax-запросы функциями GET и POST

Эти функции осуществляют отправку ajax запроса http-методами get и post. Приведу пару примеров их использования.

Передача данных не обязательна, как и выполнение каких-либо действий после получения ответа от сервера, т.е. в этом случае, строчки 3 и 4-6 можно удалить при необходимости и таким образом еще сократить код.

Тип получаемых от сервера данных можно указать, добавив dataType (см.ниже) - по-умолчанию определяется автоматически.

Использование post аналогично, но в следующем примере использую вызов функции после получения ответа от сервера.

На самом деле, функции get и post являются сокращенными вариантами функции ajax, которую рассмотрю ниже.

Получение json-данных с помощью getJSON

getJSON - укороченный вариант ajax-запроса методом GET и получением данных в виде json. Способ удобен, например, для получения какого-то массива с данными и последующей работы с ним.

На стороне сервера программа формирует массив и преобразовывает его в json-строку, например, так:

Точно так же можно передать с сервера и объекты stdClass, преобразовав их в json-строку.

Простой ajax-запрос через jQuery с помощью функции AJAX

Теперь приведу пример простого get запроса функцией ajax и получением html-данных.

Запрос к серверу происходит get-методом, т.к. параметр, отвечающий за тип запроса, type по-умолчанию равен GET.

Более сложный пример ajax-запроса через jQuery

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

Кнопка отправки данных:

В приведенном примере при нажатии на кнопку button, сначала меняется состояние кнопки (текст на ней меняется на "Отправка. " и она становится не активной), что делается при помощи параметра beforeSend. Затем происходит отправка запроса с передачей нужных данных. После того, как получен ответ от сервера состояние кнопки возвращается в прежнее (текст меняется на "Отправить", становится активной). Ответ получается в виде json-данных.

Коротко опишу параметры отправки ajax-запроса, которые чаще всего могут пригодиться:

url Адрес отправки ajax-запроса
type Способ отправки запроса GET или POST
data Отправляемые серверу данные. Может быть строка с параметрами и их значениями в формате par1=val1&par2=val2&. объект jQuery, например, $('input[type="text"]') или другие данные.
dataType Тип получаемых от сервера данных. Может быть html, json, text, script и xml.
cache Кэширование браузером запроса (false - не кэшировать).
async Асинхронное выполнение запроса, т.е. программа продолжает выполняться не дожидаясь ответа сервера. Если указать false, то запрос будет выполнен синхронно, при этом страница не будет ни на что реагировать, пока не будет получен ответ от сервера.
processData Преобразование отправляемых данных в url-формат. Если нужно чтобы данные не преобразовывались, установить в false. Например, при отправке изображения на сервер или xml-данных.
contentType Тип передаваемых данных, по умолчанию "application/x-www-form-urlencoded; charset=UTF-8". Если указать false, то в заголовке не будет передаваться тип, что может быть необходимо, например, при отправке изображения на сервер.
beforeSend Функция, выполняемая перед отправкой ajax-запроса.
complete Функция, выполняемая после получения ответа от сервера (любого, успешного или нет).
success Функция, выполняемая при удачном выполнении запроса.
error Функция, выполняемая в случае ошибки.

Ниже приведу еще несколько примеров использования ajax-запросов.

Отправка формы со всеми данными ajax-запросом через jQuery

Примерный код html-формы:

Для того чтобы страница не перезагружалась при нажатии на кнопку "submit", сначала отменяем стандартые действия браузера использовав e.preventDefaults() .

В параметре data мы передаем все поля формы использовав $(this).serialize() - эта функция преобразует все input-ы и select-ы в строку, пригодную для отправки на сервер.

Так же, здесь использован параметр async: false , чтобы пока форма не отправится на сервер больше ничего нельзя было нажать или сделать.

Отправка изображения или файла ajax-запросом через jQuery

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

html-код будет такой:

Суть идеи в том, что поверх кнопки выводится стандартный input для выбора файла, но он полностью прозрачен и имеет такие же размеры как кнопка. Таким образом, пользователь видит кнопку button, но когда наводит на нее курсор, фактически наводит на input. Соответственно, когда он нажимает на кнопку, на самом деле нажимается input выбора файла. Для того, чтобы не мигал курсор после выбора файла, размер шрифта задан 0px.

Теперь javascript код отправки файла на сервер с отображением прогресса:

При загрузке файла на сервер в кнопке будет показываться сколько % уже передано на сервер. После завершения загрузки название кнопки возвращается как было, а значение input-а с файлом устанавливается пустым, чтобы можно было снова выбирать новый файл.

Пример серверной части на php (по просьбе Евгения):

Информация о загруженном изображении будет содержаться в $_FILES['upload'] , т.к. скриптом файл добавлялся так: form.append('upload', files[0]); Соответственно, всё что требуется от php-программы - это проверить что файл соответствует ожидаемым параметрам, перенести файл в нужную папку (в примере в папку files) под нужным именем (в примере newname_image) и вернуть в браузер ответ, который в моем примере просто выводится пользователю командой alert(message);

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

Синхронная и асинхронная передача данных в Ajax

Предлагаю в самом начале статьи вспомнить, что технология AJAX расшифровывается не иначе как Асинхронный JavaScript и XML. Это и является главной особенностью технологии. В случае с асинхронной передачей данных браузер не перезагружает страницу и сам не подвисает во время ожидания ответа!

Асинхронную передачу включить легко - достаточно использовать параметр (как правило, третий по порядку) метода open(), где следует указать true (истинно). Соответственно, если поставить false, то браузер будет виснуть на время получения ответа от сервера, будь то лайк, рейтинг или ещё что. А представьте, что было до создания асинхронной передачи данных? На сервере сбой - страница зависла.

Включаем асинхронную передачу данных. Параметры open(метод передачи, действие-файл, асинхронно или синхронно).

Код JS (Ajax)

Теперь отосланный запрос будет прорабатывать независимо от других сценариев на странице, а обрабатывать он будет только при получении. Получили ответ с сервера через 20 секунд? Ну вот тогда и обработали, а не зависаем.

Асинхронная отправка

Устанавливаем параметр true в open(). Что делать, когда готов ответ, пишем в событии onreadystatechange (например, отобразить в данном объекте на странице):

Код JS (Ajax)

Синхронная передача

Внимание! Синхронную передачу описываю только из приличия. В нашем случае (рассмотрение Ajax) это всё равно, что в 21 век въехать на телеге. Тем не менее, для этого в метод open() вставляем false:

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

Внимание! Когда Вы используете параметр асинхронной передачи в false, то НЕ надо прописывать функцию обработки события onreadystatechange. Достаточно расположить код обработки после send().

Код JS (Ajax)

Спасибо за внимание!

Наконец переходим к следующему уроку с разбором примера Ajax и TXT-файла!

Технология AJAX

Введение в AJAX

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

Первоначально возможность асинхронного взаимодействия с сервером была использована в виде объекта ActiveX в компании Microsoft. В последствии идея асинхронного взаимодействия была подхвачена и другими компаниями. И в настоящее время функционал асинхронных запросов в браузерах доступен веб-разработчикам через объект XMLHttpRequest.

Поскольку данный материал посвящен jQuery, я не буду подробно останавливаться на объекте XMLHttpRequest . Но вкратце покажу суть его использования.

Итак, прежде всего для работы с AJAX нам нужен веб-сервер. Это может быть Node.js, IIS, Apache, nginx. В дальнейшем я буду использовать веб-сервер Apache.

Создадим веб-страничку, где будет использоваться XMLHttpRequest:

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

Все основное действие у нас происходит в функции ajaxload. Во-первых, мы создаем объект XMLHttpRequest: var xhr=new XMLHttpRequest(); .

Через этот объект мы будем отправлять запросы. При получении ответа будет срабатывать событие onreadystatechange. И для обработки данного события мы присваиваем свойству xhr.onreadystatechange функцию обработки ответа.

В функции обработки мы, во-первых, смотрим на готовность ответа через свойство readyState (состояние this.readyState==4 означает, что запрос завершен). Далее мы проверяем статусный код ответа: если сервер возвратил статусный код от 200 до 300, то запрос прошел успешно.

И затем мы передаем текст ответа в блок div, который у нас имеется на странице через свойство responseText .

В строке xhr.open('GET', 'ajax.php'); мы устанавливаем метод запроса и ресурс, к которому будет идти запрос.

Ну и последней строчкой xhr.send() отправляем запрос. В итоге мы написали очень много кода, чтобы выполнить простой запрос.

Пусть у нас на сервере находится обработчик запросов на языке php. Я сделаю его предельно простым. Он будет просто передавать в ответ разметку html:

Теперь по нажатию по кнопке будет происходить ajax-запрос, результаты которого будут загружаться на страницу:

Теперь перепишем код страницы с использованием jQuery:

Таким образом, код становится чище и проще за счет использования библиотеки jQuery. Нам достаточно применить метод load , передав в качестве параметра адрес ресурса. И итоговый результат будет тот же самый.

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