Хотя архитектура Ajax может быть реализована поверх транспорта
<iframe>
или
<script>,
существует более простой путь. Уже достаточно давно все броузеры стали поддерживать объект
XMLHttpRequest
, определяющий прикладной интерфейс для работы с протоколом HTTP. Этот интерфейс обеспечивает возможность выполнять POST-запросы в дополнение к обычным GET-запросам и может возвращать ответ веб-сервера синхронно или асинхронно, в виде простого текста или в виде объекта
Document
. Несмотря на свое название, объект
XMLHttpRequest
не ограничивается
использованием XML-документов - он в состоянии принимать любые текстовые документы. Прикладной интерфейс объекта
XMLHttpRequest
рассматривается в разделе 18.1, который занимает значительную часть главы. Большая часть примеров реализации архитектуры Ajax в этой главе в качестве транспорта использует объект
XMLHttpRequest
, но в разделе 18.2 также будет показано, как использовать транспорт на основе элемента
<script>,
так как он способен обходить ограничения политики общего происхождения.
Транспортные механизмы в архитектуре Comet сложнее, чем в архитектуре Ajax, но все они требуют установления (и восстановления, в случае необходимости) соединения с сервером со стороны клиента и обязывают сервер поддерживать соединение открытым, чтобы через него можно было отправлять асинхронные сообщения. Транспортом в архитектуре Comet может служить, например, скрытый элемент
<iframe>,
если сервер отправляет сообщения в виде элементов
<script>,
выполняемых в элементе
<iframe>.
Более надежный и переносимый подход к реализации архитектуры Comet заключается в том, чтобы клиент устанавливал соединение с сервером (используя Ajax-транспорт), а сервер поддерживал это соединение открытым, пока имеется необходимость отправлять сообщения. Каждый раз, когда сервер отправляет сообщение, он закрывает соединение, что позволяет гарантировать благополучное получение сообщения клиентом. После обработки сообщения клиент может сразу же установить новое соединение для будущих сообщений.
Реализация надежного и переносимого транспорта для архитектуры Comet является сложной задачей, и большинство веб-разработчиков, использующих архитектуру Comet, опираются на транспорты, реализованные в веб-фреймворках, таких как Dojo. На момент написания этих строк производители броузеров приступили к реализации положений проекта спецификации «Server-Sent Events», связанной со стандартом HTML5, которая определяет простой прикладной интерфейс для архитектуры Comet в виде объекта
EventSource
. Интерфейс объекта
EventSource
будет рассматриваться в разделе 18.3 и там же будет продемонстрирована простая его имитация на основе объекта
XMLHttpRequest
.
Имеется также возможность конструировать высокоуровневые протоколы взаимодействий поверх Ajax и Comet. Эти приемы организации взаимодействий типа клиент/сервер можно использовать, например, в качестве основы механизма RPC (Remote Procedure Call - вызов удаленных процедур) или системы событий типа издатель/подписчик. Однако в данной главе мы не будем рассматривать подобные высокоуровневые протоколы, а сконцентрируемся на прикладных интерфейсах поддержки архитектур Ajax и Comet.
Использование XML не является обязательным
Символ «X» в аббревиатуре «Ajax» обозначает «XML». Основной прикладной интерфейс для работы с протоколом HTTP на стороне клиента (
XMLHttpRequest
) также содержит название «XML» в своем имени, и, как мы узнаем далее, одно из свойств объекта
XMLHttpRequest
имеет имя
responseXML
. Вследствие этого может сложиться впечатление, что XML является важной частью работы с протоколом HTTP. Но это не так: эти имена являются историческим
наследием тех дней, когда XML было модным словечком. Конечно, реализации Ajax способны работать с XML-документами, но использование формата XML является необязательным, и в действительности он редко используется не практике. Спецификация
XMLHttpRequest
полна несоответствий в именах, с которыми нам придется сталкиваться:
Имя объекта
XMLHttpRequest
было выбрано исходя из соображений совместимости с Веб, хотя каждая часть этого имени может вводить в заблуждение. Во-первых, объект поддерживает любые текстовые форматы, включая XML. Во-вторых, он может использоваться для отправки запросов по обоим протоколам, HTTP и HTTPS (некоторые реализации могут поддерживать дополнительные протоколы, помимо HTTP и HTTPS, но эти возможности не регламентируются в спецификации). Наконец, он поддерживает «запросы» («requests») в более широком смысле, - как это подразумевает использование протокола HTTP. А именно, все операции, связанные с выполнением HTTP-запросов или получением НТТР-ответов для определенных НТТР-методов.
******************************************
18.1. Использование объекта XMLHttpRequest
Прикладной интерфейс к протоколу HTTP в броузерах определяется в виде класса
XMLHttpRequest
. Каждый экземпляр этого класса представляет единственную пару запрос/ответ, а свойства и методы объекта позволяют определять параметры запроса и извлекать данные из ответа. Объект
XMLHttpRequest
поддерживается вебброузерами уже довольно давно, а его прикладной интерфейс находится на последних стадиях стандартизации консорциумом W3C. В то же время в консорциуме W3C ведутся работы над проектом стандарта «XMLHttpRequest Level 2». В этом разделе мы рассмотрим базовый прикладной интерфейс объекта
XMLHttpRequest
, а также те части проекта стандарта «XMLHttpRequest Level 2» (я называю его «XHR2»), которые в настоящее время реализованы как минимум в двух броузерах.
Первое, что обычно необходимо сделать при использовании этого прикладного интерфейса к протоколу HTTP, это, разумеется, создать экземпляр объекта
XMLHttpRequest
:
var request = new XMLHttpRequest;
Допустимо повторно использовать уже имеющийся экземпляр объекта
XMLHttpRequest
, но следует иметь в виду, что в этом случае будет прервано выполнение запроса, уже отправленного объектом.
XMLHttpRequest в IE6
Корпорация включила поддержку объекта
XMLHttpRequest
в свой броузер IE, начиная с версии 5. В версиях IE5 и IE6 этот объект доступен только в виде ActiveX-объекта. Поддержка современного стандартного конструктора
XMLHttpRequest
появилась только в IE7, но его можно имитировать, как показано ниже:
// Имитация конструктора XMLHttpRequest в IE5 и IE6
if (window.XMLHttpRequest === undefined) {
window.XMLHttpRequest = function {
try {
// Использовать последнюю версию ActiveX-объекта, если доступна