Программирование объекта XMLHttpRequest

Порядок создания экземпляра объекта XMLHttpRequest зависит от броузера, в котором исполняется программный код. Следующий фрагмент будет работать в Internet Explorer 5 и выше. Из?за разных версий библиотеки Microsoft XML, которые поставляются с разными версиями Internet Explorer, в данном фрагменте производится попытка соз?дать экземпляр XMLHttpRequest двумя разными способами. Чтобы избежать появления сообщений об ошибках при неудачном завершении одного из методов, используются две конструкции try?catch:

var XMLHTTP = null;
try {
XMLHTTP = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
XMLHTTP = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e) {
}
}

В броузерах, отличных от Internet Explorer, синтаксис создания объекта намного проще:
XMLHTTP = new XMLHttpRequest();

Таким образом, все, что необходимо сделать, – это определить тип используемого броузера и выбрать соответствующий метод создания экземпляра XMLHttpRequest. Например, следующий фрагмент выясняет возможность создания объекта ActiveX путем проверки наличия свойства ActiveXObject у объекта window.


Если свойство присутствует, значит, сценарий исполняется в Internet Explorer.

if (window.ActiveXObject) {
// скорее всего, это IE
}

Для тех же целей можно использовать следующий фрагмент, который проверяет присутствие объекта XMLHttpRequest. При положительном результате это означает, что сценарий исполняется в Mozilla или его производных, Opera, Konqueror или Safari:

if (XMLHttpRequest) {
// скорее всего, это не IE
}

Однако, непосредственная проверка наличия объекта XMLHttpRequest в Internet Explorer вызывает появление сообщения об ошибке «XMLHttpRequest is undefined» (объект XMLHttpRequest не определен). Положение вещей должно измениться с выходом Internet Explorer 7, который будет иметь встроенную реализацию объекта XMLHttpRequest1.

Необходимо реализовать какой?то иной подход к выполнению проверок, показанных выше. В JavaScript имеется оператор typeof, который используется для определения типа выражения и возвращает строку«undefined», если выражение дает в результате значение «undefined».

Следующий фрагмент позволяет определить броузеры, отличные от Internet Explorer:

if (typeof XMLHttpRequest != "undefined") {
// это не IE версии 6 или ниже
}

Далее представлен исходный текст функции getXMLHTTP(), которая объединила в себе все предыдущие фрагменты.


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

function getXMLHTTP() {
var XMLHTTP = null;
try {
XMLHTTP = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
XMLHTTP = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e) {
if (typeof XMLHttpRequest != "undefined") {
XMLHTTP = new XMLHttpRequest( );
}
}
}
return XMLHTTP;
}

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

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

function getXMLHTTP() {
var XMLHTTP = null;
if (window.ActiveXObject) {
try {
XMLHTTP = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
XMLHTTP = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e) {
}
}
} else if (window.XMLHttpRequest) {
try {
XMLHTTP = new XMLHttpRequest( );
} catch (e) {
}
}
return XMLHTTP;
}

Объект XMLHttpRequest, независимо от того, в каком броузере он был создан, имеет набор свойств и методов, которые используются для передачи HTTP?запросов и получения ответов от сервера.


В большинстве ситуаций, чтобы сгенерировать HTTP?запрос и получить возвращаемые значения, необходимо выполнить следующие четыре действия:

1. Создать объект XMLHttpRequest, как было показано в предыдущих примерах.

2. Вызвать метод open() объекта для подготовки запроса.

Метод open() ожидает получить пять параметров, но обычно достаточно определить два первых: тип метода выполнения запроса (обычно «GET» или «POST») и строку адреса URL (относительный или абсолютный).

Третий параметр метода open() по умолчанию принимает значение true – это означает асинхронный режим выполнения запроса. Если в этом аргументе передать значение false, запрос будет исполнен в синхронном режиме, то есть исполнение сценария будет приостановлено до момента получения ответа сервера. В большинстве случаев используется асинхронный режим, поэтому вам нужно либо опустить этот параметр, либо передать в нем значение true. Если для вы?полнения HTTP-запроса требуется аутентификация, тогда в четвертом и пятом аргументах можно передать имя пользователя и пароль.

3. Записать в свойство onreadystatechange ссылку на функцию обратного вызова. Эта функция будет вызвана при получении ответа на запрос.

4.


Отправить HTTP?запрос вызовом метода send(). Этот метод отправит HTTP?запрос. Если перед этим был выбран асинхронный режим работы, метод send() немедленно вернет управление и пользователь сможет продолжить работу со страницей.

Посредством свойства onreadystatechange объект XMLHttpRequest предоставляет механизм обратных вызовов, который используется для обработки ответа. Как следует из имени свойства, это должна быть функция, которая определяет реакцию на изменение значения другого свойства объекта XMLHttpRequest – readyState. Свойство readyState указывает на состояние объекта XMLHttpRequest и может иметь одно из пяти возможных значений.

Всякий раз, когда изменяется значение readyState, вызывается функция, указанная в свойстве onreadystatechange. В этой функции сначала необходимо проверить значение readyState. Как правило, наибольший интерес представляет значение 4, которое означает, что был получен полный ответ.

Когда функция вызывается в ответ на изменения в readyState, в игру вступают и другие свойства объекта XMLHttpRequest. Свойство status содержит код HTTP?статуса, полученный в ответ на запрос – если все в порядке, статус имеет значение 200.


Свойство statusText содержит соответствующее текстовое описание HTTP?статуса. Например, для статуса с кодом 200 в свойстве statusText будет находиться строка "OK".

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

Доступ к данным, полученным от сервера, можно получить с помощью двух свойств: responseText
Возвращает полученные данные в виде строки responseXML
Возвращает полученные данные в виде XML-документа.

Следующий сценарий – это небольшой пример, иллюстрирующий порядок использования объекта XMLHttpRequest. В примере выполняется запрос к странице ASP.NET с именем ajax.aspx. На первом этапе с помощью функции getXMLHTTP(), которая была описана ранее, создается объект XMLHttpRequest. В случае успеха (то есть когда функция возвращает значение, отличное от null) выполняется подготовка GET-запроса с параметром sendData=ok (это значение было выбрано лишь для этого примера, а вообще оно может быть любым другим). Затем в свойство onreadystatechange записывается ссылка на функцию, и в заключение запрос отправляется серверу.

var XMLHTTP = getXMLHTTP();
if (XMLHTTP != null) {
XMLHTTP.open("GET", "ajax.aspx?sendData=ok");
XMLHTTP.onreadystatechange = stateChanged;
XMLHTTP.send(null);
}

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

function stateChanged( ) {
if (XMLHTTP.readyState == 4 &&
XMLHTTP.status == 200) {
window.alert(XMLHTTP.responseText);
}
}

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

Разумеется, на стороне сервера должен иметься некоторый программный код, который возьмет на себя обработку запроса, произведенного объектом XMLHttpRequest. В следующем фрагменте, написанном на языке C#, демонстрируется функция?обработчик Page_Load, которая находится на странице ASP.NET и отвечает на асинхронный запрос, выполняемый объектом XMLHttpRequest:

void Page_Load() {
if (Request.QueryString["sendData"] != null &&
Request.QueryString["sendData"] == "ok")
{
Response.Write("Hello from the server!");
Response.End();
}
}

В примере 3.1 демонстрируется страница ajax.aspx, которая объединяет в себе все составные части (клиентский сценарий и программный код, исполняемый на стороне сервера).

Пример 3.1. Простой пример, объединяющий Ajax и ASP.NET ajax.aspx
<%@ Page Language="C#" %>
"http://www.w3.org/TR/xhtml1/DTD/xhtml1?transitional.dtd">
Ajax with ASP.NET


(body)

Wait and see ...


(/body)


Как видно на рис. 3.2, 3.3 и 3.4, этот пример прекрасно работает в Internet Explorer, Firefox и Konqueror (в последнем случае ASP.NET работает в среде Mono), то есть в наиболее распространенных броузерах.

Этот пример должен работать и в других броузерах при условии, что в них будет включена поддержка JavaScript.

Если требуется отправлять HTTP?запросы методом POST, необходимо соответствующим образом определить первый параметр метода open().

Использование метода POST имеет смысл, когда возникает необходимость передачи больших объемов данных, от 500 и более байт (то есть может быть превышена максимальная длина строки URL, которую способен принимать сервер), или когда требуется предотвратить кэширование на прокси?сервере. Отправляемые данные передаются функции send() в виде пар имя?значение, при необходимости с URL-кодированием (URL?encoded), как показано в следующем фрагменте:

XMLHTTP.open("POST", "ajax.aspx");
XMLHTTP.onreadystatechange = stateChanged;
XMLHTTP.send("sendData=ok&returnValue=123");

На стороне сервера для чтения данных, отправленных методом POST, вместо свойства Request.QueryString, которое используется для доступа к GET?запросам, следует использовать Request.Form.

При обращении к веб-службам, использующим протокол SOAP, можно отправлять текст непосредственно в формате XML, без преобразования его в формат URL. Однако, чтобы такой прием работал в броузерах Safari и Konqueror (что позволит максимально расширить круг посетителей), необходимо явно установить тип содержимого запроса в значение text/xml. (Другие броузеры не требуют явного указания типа содержимого.) В следующем фрагменте демонстрируется, как это сделать:

XMLHTTP.open("POST", "ajax.aspx");
XMLHTTP.onreadystatechange = stateChanged;
XMLHTTP.setRequestHeader("Content?Type", "text/xml");
XMLHTTP.send("...");

Теперь немного о безопасности: по умолчанию объект XMLHttpRequest обладает доступом только к ресурсам, расположенным в том же домене, где находится страница, содержащая клиентский сценарий. К сожалению, это ограничивает возможности технологии, поскольку нет достаточно простого способа обращения к веб?службам с использованием Ajax, размещенным за пределами вашего домена. Броузеры Mozilla поддерживают возможность доступа к удаленным серверам в других доменах, но при этом они явно запрашивают у пользователя разрешение на получение дополнительных привилегий.

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

Оцените статью: (0 голосов)
0 5 0

Статьи из раздела ASP.NET AJAX на эту тему:
JSON
Объект XMLDocument
Объект XMLHttpRequest

Вернуться в раздел: ASP.NET AJAX / Ajax