Ajax и клиент-серверная архитектура.
Использование AJAX и Rich Client серьезно отражается не только на серверной и клиентской части приложения, но и на их взаимодействии.
В статье описывается расширенная странично-сервисная модель приложения, MVC на клиенте и несколько принципов реализации сложных AJAX-приложений.
В классической модели MVC работа с сайтом выглядит следующим образом.
На рисунке изображен один из частых вариантов MVC. Это - странично-ориентированная архитектура.
С другой стороны, AJAX приводит нас к сервисно-ориентированной архитектуре:
Для поддержки посетителей с выключенным javascript также используют смешаную архитектуру. Один из способов ее реализации - снабжать AJAX-запросы специальными заголовками.
Например, для формы голосования
...
<form action="/module/vote.html" method="post" onsubmit="send_vote(); return false">
... <input type="submit" value="Голосовать"> ...
</form>
Если javascript выключен - форма просто запостит данные на /module/vote.html и выведет эту HTML-страницу. Для пользователей с включенным javascript запустится
функция send_vote(), которая отправит точно такой же POST-запрос, но дополнительно поставит заголовок 'AJAX'.
//... в коде функции send_vote ...
request.setRequestHeader('AJAX',1)
Получив запрос с таким заголовком, сервер поймет, что результат надо
выводить не в виде обычной страницы, а в формате ответа на AJAX-запрос, например JSON.
При этом для обработки обоих видов запроса используется одна и та же модель и контроллер, который в зависимости от наличия заголовка переключается
между режимами "генерация страницы" и "вызов сервиса".
На клиенте естественным образом возникает паттерн MVC, только вместо серверных языков используются скрипты и объекты браузера.
- Модель
- Содержит внутреннее представление данных в браузере. Например, "корзина" в онлайн-магазине, ее свойства и товары в ней, как правило, реализуются через JavaScript-объекты.
- Представление (Вид)
- Отображение на экран происходит при помощи DOM. Различные эффекты и элементы интерфейса организуются через манипуляцию их свойствами.
- Контроллер
- Код, который связывает модель с представлением и обрабатывает события.
Почти все web-приложения, перешагнувшие некоторый порог функционала, соблюдают ряд архитектурных решений.
В классических веб-приложениях сервер хранит все необходимые данные для генерации страниц. В ответ на действия пользователя он, учитывая сессию, создает новую страницу. Браузер выбрасывает старый документ и показывает новый.
Роль браузера проста и незатейлива.
Однако, занесение товара в корзину покупателя вряд ли изменит список категорий и продуктов. Поэтому можно при помощи AJAX отправить информацию о добавленном продукте на сервер. Например, через XML-сообщение:
<action>addToCart</action>
<productId>151</productId>
Если такой товар может быть добавлен, то сервер ответит
<status>OK</status>
и браузер (а, точнее, наше JavaScript-приложение) самостоятельно обновит корзину на экране.
Информация о текущем состоянии корзины может, вообще, отсутствовать на сервере и храниться только на клиенте.
Таким образом, виден побочный эффект - уменьшение нагрузки на сервер, т.к часть ее берет на себя "умный" клиент, приложение на стороне браузера.
Как видно из примера выше, браузер получает с сервера совсем не HTML документ.
Со своей стороны он отправляет специальный запрос, а со стороны сервера получает стандартный ответ, который использует для обновления информации.
Вообще говоря, AJAX может использоваться и для пересылки готового HTML. Такой подход, как правило, применяется либо для облегчения клиентской части, либо для небольшого внедрения AJAX в классическое приложение.
Большинство разработчиков соглашаются, что чем сложнее клиентское приложение, тем выгоднее обмениваться данными вместо документов.
При работе синхронного приложения пользователь запрашивает данные с сервера и оказывается в своего рода "лимбо" - нечего делать, пока создается и загружается новая страница.
В AJAX-корзине пользователь может добавлять все новые товары, открывать новые категории дерева товаров непрерывно.
Паузы в работе приложения отвлекают мысли пользователя, особенно начиная с некоторой границы, которую разные исследователи ставят от 0.1 до 3 сек.
Их отсутствие открывает новый уровень интерактивности в работе с веб-приложениями.
Роль JavaScript в классических веб-приложениях невелика. Как правило, она сводится к созданию различных эффектов и оригинальных меню.
Такое программирование, как правило, не требует ни глубоких знаний, ни ООП и в свое время принесло JavaScript незаслуженную репутацию непонятного и сложного для освоения языка.
С другой стороны, AJAX-приложение, нацеленное на долгую работу в браузере, должно иметь расширяемую базу, грамотную архитектуру и учитывать особенности среды, в которой работает: быстродействие, управление памятью и т.п.
|
отличный ресурс
"Информация о текущем состоянии корзины может, вообще, отсутствовать на сервере и храниться только на клиенте."
ну это получается только если страница не обновляется, и даже форма платежа грузится асинхронно? или я что-то не знаю?
Да, есьт даже движки - целиком на ajax. Конечно, в этом случае предусматривается возможность просмотра сайта без AJAX анонимным посетителем. Для поисковиков.
познавательная статья! спасибо!
Спасибо за статью. Хотелось бы уточнить один момент: как именно в следующем коде произойдет выбор дествия в зависимости от выкл/вкл javascript, что из кода выполниться и когда?
Sorry, но только начал осваивать, наверное нехватает знаний синтаксиса.
Если JS включен, то выполнится обработчик события onsubmit у формы и перехода на action не произойдет. Если же JS выключен, то обработчик выполнен не будет, и браузер отправит post запрос по адресу /module/vote.html.
ну это врядли... стандартно html файл не принимает post. умный IE будет протестовать...
Получив запрос с таким заголовком, сервер поймет, что результат надо
выводить не в виде обычной страницы, а в формате ответа на AJAX-запрос, например JSON.
Как считывать такой заголовок в серверном скрипте (PHP)?
Все заголовки, отправленные браузером, лежат в массиве $_SERVER и начинаются с префикса HTTP_.
В нашем случае $_SERVER['HTTP_AJAX'] будет равно 1.