Рассматривая ту или иную новую технологию прежде всего необходимо разобраться для чего эта самая технология необходима и что именно она позволяет (или облегчает) делать, что не позволяют делать другие технологии. Чтобы более наглядно понять, какие предпосылки были к появлению AJAX, можно рассмотреть процесс эволюционного развития web-сайтов.
На самой заре развития интернет сайты представляли собой набор простых статических страниц – пользователь запрашивал ресурс у сервера и сервер возвращал статическую страницу. Эта страница представляла собой простой HTML текст и хранилась как текстовый файл на сервере. Данная страница поставлялась пользователю as is и, кроме того, не имела никаких клиентских скриптов.
CGI
Первая попытка сделать страницы более динамичными был Common Gateway Interface (CGI). CGI позволял разработчику создавать исполняемые программы, которые генерировали страницу, что позволяло принимать параметры от пользователя. С учетом этих параметров можно было генерировать уникальную страницу. По большому счету, данный подход используется и сейчас в том же ASP.NET, PHP и т.д.
JavaScript
Генерация страниц на серверной стороне это конечно хорошо, но это вынуждало при каждом, даже самом незначительном действии пользователя, делать запрос к серверу с перегрузкой всей страницы. Чтобы не перегружать всю страницу в случаях, когда участие сервера абсолютно не нужно, стали использоваться клиентские скрипты.
Апплеты и Flash
В случае, если запрос к серверу все же необходим и одними клиентскими скриптами не обойтись – разработчики в web-страницах стали использовать т.н. апплеты а также flash.
Апплеты впервые были использованы в 1995 году, когда Sun представила миру на всеобщее обозрение свою новую платформу с новым языком – JAVA. По сути апплеты представляли собой программы, написанные на JAVA и которые могли запускаться в броузере как отдельные приложения. Для того, чтобы эта программа, написанная на неведомом для броузера языке JAVA, могла быть запущена внутри броузера, необходимо было установить JVM (Java Virtual Machine) – среду для выполнения программ JAVA. И хотя данный подход звучит очень заманчиво – он имел множество недостатков, прежде всего это проблемы безопасности (не каждый пользователь, путешествуя по интернет, разрешит запускать на своем компьютере программы непонятного происхождения) и необходимость громозкой VM. Несмотря на то, что помимо общения с сервером апплеты и флеш также позволяли реализовать возможности, недоступные JavaScript (скажем, более высокие требования к графике) – те сложности не дали апплетам прижиться настолько, чтобы окончательно решить проблемы с запросами к серверу.
DHTML
Dynamic HTML объединил в себе HTML, каскадные таблицы стилей (CSS) и JavaScript. Также ко всему этому набору добавился DOM – объектная модель броузера. Вся эта смесь позволяла (и позволяет) успешно создавать очень красивые, удобные и функциональные страницы «на лету». Но опять же, в случае, если нужно выполнить запрос к серверу – приходится перегружать весь документ.
AJAX
Решение этой проблемы пришло с появлением новой технологии, которая в 2004 году была названа AJAX (Asynchronous JavaScript + XML). Данная технология построена на принципе выполнения запроса к серверу с использованием JavaScript и получению результата опять же, с помощью JavaScript, что позволяет избежать перегрузки страницы и следовательно имеет несколько неоспоримых преимуществ:
1. На сервер отправляются не все элементы страницы (точнее не их значения), а только те минимальные данные, которые необходимы для выполнения того или иного запроса и в ответ принимается не вся страница, а только необходимые данные, что позволяет уменьшить трафик в десятки (а иногда и в сотни) раз. 2. Не происходит перегрузка страницы в броузере и у пользователя создается впечатление, что все происходит на его компьютере.
Об этой технологии и пойдет дальше речь. Объектная модель броузера.
Если вы меня спросите на чем основан принцип работы технологии AJAX, то я вам наверное отвечу : «благодаря объектной модели броузера». Что же это за такая объектная модель броузера (DOM)?
Document Object Model (DOM) – это спецификация, стандартизированная W3C комитетом, которая является кроссплатформенной и описывает вызовы и описания, касающиеся действиям с самим документом, его структурой, HTML, XML и стилями. Как следует из названия, основой спецификации DOM являются объекты.
Объект XMLHttpRequest
Этот объект появился впервые в Internet Explorer 5.0 и был реализован как ActiveX компонент. Важно заметить, что этот объект не является стандартом W3C, хотя многое из его функциональности описано в спецификации «The DOM Level 3 Load and Save Specification». По этой причине его поведение может немного отличаться в различных броузерах. Но во всех броузерах он выполняет одну и ту же функциональность – он умеет посылать запросы к серверу и получать от него ответы. Как уже говорилось выше, данный объект не стандартизирован и создание его instance может отличаться в различных версиях, поэтому для «надежного» его создания лучше использовать код, который объединяет в себе создание instance в нескольких броузерах подобно коду ниже:
var xmlHttp; function createXMLHttpRequest() { if (window.ActiveXObject) { xmlHttp = new ActiveXObject("Microsoft.XMLHTTP"); } else if (window.XMLHttpRequest) { xmlHttp = new XMLHttpRequest(); } }
XMLHttpRequest имеет ряд «стандартных» (стандартных в кавычках т.к. как писалось выше, данный объект не стандартизирован для всех броузеров) свойств и методов, которые позволяют данному объекту посылать запрос, проверять состояние запроса и получать результат выполнения запроса от удаленного сервера. Эти свойства и методы мы рассмотрим в следующих двух таблицах.
В таблице 1 представлены «стандартные» свойства XMLHttpRequest
Метод
Описание
abort()
Прерывает текущий запрос
getAllResponseHeaders()
Возвращает все заголовки Response в виде ключ/значение
getResponseHeader(header)
Возвращает значение определенного заголовка
open(method, url, asynch, username, password)
Устанавливает состояние запроса к серверу. Первый параметр указывает метод запроса – PUT, GET, POST, второй – url запроса, третий (необязательный) – тип запроса (синхронный или асинхронный), четвертый и пятый (также необязательные) – для защищенных страниц
send(content)
Посылает запрос серверу
setRequestHeader(header, value)
Устанавливает значение определенного заголовка. Перед вызовом этого метода необходимо вызвать метод open
Также XMLHttpRequest содержит ряд свойств, которые представлены ниже:
Свойство
Описание
onreadystatechange
Обработчик события, которое возникает при каждой смене состояния запроса
Ответ от сервера в XML. Этот объект может быть обработан и проверен как DOM
status
Код статуса HTML.(например 200 – OK)
statusText
Название кода статуса HTML
Бегло проглянув эти методы, несложно понять, какие методы достаточно вызвать, чтобы с помощью JavaScript получить какие-либо с сервера.
Прежде всего напишем серверную часть, которая будет возвращать простую строку. Для этого (чтобы не было «посторонних» данных вроде тегов открытия закрытия html) наиболее рационально будет создать hanlder. Открываем web-проект в Visual Studio 2005 и создаем файл типа Handler. Содержимое будет примерно следующим:
<%@ WebHandler Language="C#" Class="MyHandler" %> using System; using System.Web; public class MyHandler: IHttpHandler { public void ProcessRequest (HttpContext context) { context.Response.ContentType = "text/plain"; context.Response.Write("Hello World"); } public bool IsReusable { get { return false; } } }
Т.е. при запросе данной страницы этот hanlder возвращает text/plain документ с единственной строчкой “Hello World”. Нас такой handler устраивает как нельзя лучше.
Теперь создадим обычную HTML – страницу, которая будет и выполнять запрос, используя XMLHttpRequest.
<html xmlns="http://www.w3.org/1999/xhtml" > <head> <title>Simple XMLHttpRequest pagetitle> <script type="text/javascript"> var xmlHttp; function createXMLHttpRequest() { if (window.ActiveXObject) { xmlHttp = new ActiveXObject("Microsoft.XMLHTTP"); } else if (window.XMLHttpRequest) { xmlHttp = new XMLHttpRequest(); } } function startRequest() { createXMLHttpRequest(); xmlHttp.onreadystatechange = handleStateChange; xmlHttp.open("GET", "MyHandler.ashx", true); xmlHttp.send(null); } function handleStateChange() { if(xmlHttp.readyState == 4) { if(xmlHttp.status == 200) { alert("Response: " + xmlHttp.responseText); } } }