Новый подход к написанию веб-приложений

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

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

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

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

Чего не хватает веб-приложениям?

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

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

Первый шаг к решению этой проблемы сделала компания Microsoft, внедрив в Explorer 5.0 компонент XMLHttpRequest в виде объекта ActiveX, доступного через JScript, VBScript или другие скриптовые языки, поддерживающиеся браузером. Чуть позже программисты из проекта Mozilla разработали версию этого компонента, совместимую с браузером Mozilla 1.0, а затем реализация этого объекта появилась в Safari 1.2, Konqueror, Opera 8.0 и т.д.

Объект XMLHttpRequest позволяет скрипту осуществлять HTTP-запрос к серверу не перезагружая страницу. Причем HTTP-запросы отправляются и принимаются без участия пользователя. Сервер в ответ генерирует не всю страницу, а лишь запрашиваемый фрагмент. Ответ может возвращаться либо в виде готового HTML-блока, либо в формате XML. В последнем случае приложение уже на клиентской стороне преобразует ответ в HTML согласно спецификации DOM.

Сейчас на рассмотрении консорциума W3C находится проект стандарта Ajax (Asynchronous JavaScript + XML, Асинхронный JavaScript + XML) — технологии, определяющей совместное использование JavaScript и XMLHttpRequest. В России почему-то Ajax чаще произносят как «аякс», но к греческой мифологии название не имеет никакого отношения. Так что правильнее было бы говорить «аджакс».

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

В целом работа веб-приложений, использующих идею Ajax, заключается в следующем:

  • пользователь открывает в браузере страницу сайта и выполняет какие-либо действия - вводит текст в поисковой строке, отмечает нужные параметры или нажимает выбранные кнопки;
  • скрипт, описывающий обработчик события для выбранного пользователем элемента (кнопки, строки или кнопки с независимой фиксацией), определяет требуемую для изменений информацию и формирует запрос;
  • браузер отправляет запрос на сервер;
  • сервер возвращает необходимую информацию (фрагмент документа);
  • скрипт (JavaScript) обновляет информацию в нужном месте страницы без перезагрузки всего документа.
Сервис GoogleSuggest, построенный на основе технологии Ajax

Что может Ajax

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

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

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

Разумеется, это далеко не единственный пример использования подхода Ajax. Уже сейчас некоторые компании реализуют свои интернет-услуги на базе этой идеи. Пожалуй, самый часто приводимый пример — это сервис Google Suggest. Здесь при вводе слова в поисковой строке система буквально на лету формирует список наиболее популярных запросов, включающих его. В то время как пользователь продолжает печатать, скрипт, обрабатывающий событие ввода в строке, обращается на сервер, откуда в ответ приходит перечень наиболее популярных запросов.

С помощью Ajax также реализованы Google Maps и почтовый веб-клиент Gmail.

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

Кстати, такой подход неоценим при персональной настройке сервисов.

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

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

Именно здесь применение технологии Ajax дает возможность порталу и пользователям облегчить настройку вида отдельных страниц и делать это проще, чем обычно. Наиболее полно возможности настройки пользовательского интерфейса портала демонстрирует проект Protopage (http://protopage.com).

Проект Protopage демонстрирует возможности гибкой настройки вида страницы без ее перезагрузки

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

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

Как работает Ajax?

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

Создаем объект XMLHttpRequest, помня о том, что реализация его для браузеров различается. В Internet Explorer это будет объект ActiveX.

var XMLCounter;
function loadXML(url)
{
// для ActiveX-реализации объекта в IE
if (window.ActiveXObject) {
XMLCounter = new ActiveXObject
("Microsoft.XMLHTTP");
if (XMLCounter) {
XMLCounter.onreadystatechange = processCount;
XMLCounter.open("GET", url, true);
XMLCounter.send();
}
}//Для остальных браузеров
else if (window.XMLHttpRequest) {
XMLCounter = new XMLHttpRequest();
XMLCounter.onreadystatechange = processCount;
XMLCounter.open("GET", url, true);
XMLCounter.send(null);
}
}

В данном фрагменте кода важны свойство onreadystatechange рассматриваемого XML-объекта и функция-обработчик processCount, выполняющая основную задачу — изменение счетчика.

Свойство onreadystatechange, отражающее текущее состояние запроса, имеет пять возможных значений:

0 - uninitialized (не инициализирован) - имеет место перед началом работы объекта XMLHttpRequest;

1 - loading (загрузка) - появляется при инициализации объекта XMLHttpRequest;

2 - loaded (загружен) - возникает лишь однажды, когда приходит ответ от сервера;

3 - interactive (доступен) - определяется до тех пор, пока объект XMLHttpRequest соединен с сервером;

4 - complete (завершен) - устанавливается после завершения объектом XMLHttpRequest всех задач.

Поскольку нам интересно последнее состояние, именно его и будем проверять при написании функции processCount.

function processCount()
{
// только если запрос завершен
if (XMLCounter.readyState == 4) {
// Если статус выполнения запроса "OK"
if (XMlCounter.status == 200) {
updateDoc('Counter',XMLCounter.responseXML.
getElementsByTagName('data')[0].firstChild.data);
} else {
alert("Невозможно получить данные:
"
 +XMLCounter.statusText);
}
}
}

Следует обратить внимание на функцию updateDoc. У нее два параметра. Первый, Counter, — идентификатор элемента в рассматриваемом документе (того самого счетчика, который будет меняться).

На странице идентифицируем его так:


...

Товаров в корзине:

... ...

После нажатия кнопки Add срабатывает ее обработчик, функция AddToChart(value), которая, в свою очередь, создает объект XMLHttpRequest и отправляет на сервер запрос:

function AddToChart(value)
{
loadXMLDoc('/addtochart.php'+'ID='+value);
}

Текст PHP-приложения здесь приводиться не будет; стоит отметить лишь, что, добавив товар к заказу, он возвращает новое количество товаров в корзине.

Наконец, последний шаг — добавление полученного от сервера ответа в страницу — обеспечивает функция updateDoc:

function updateDoc(obj, data)
{
document.getElementById(obj).firstChild.data
 = 'Товаров в корзине:' + data;
}

Эта функция просто определяет объект в документе по указанному ID и присваивает ему новое значение. В данном случае по идентификатору Counter устанавливается позиция счетчика на странице и он получает измененное значение.

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

Наиболее популярны следующие библиотеки:

  • Atlas - инструментарий корпорации Microsoft, естественно ориентированный на разработку Ajax-приложений в среде ASP.NET;
  • Google Web Toolkit - инструмент от Google для разработки на Java;
  • xAjax - набор библиотек для PHP-программистов;
  • CGI-Ajax - модуль для разработки приложений на Perl;
  • CPAINT (Cross-Platform Asynchronous INterface Toolkit) - как следует из названия, универсальный инструмент, поддерживающий сразу несколько языков программирования.

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

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