XMLHttpRequest (XMLHTTP, XHR) — API, доступный в скриптовых языках браузеров, таких как JavaScript. Использует запросы HTTP или HTTPS напрямую к веб-серверу (информация может передаваться в любом текстовом формате, например, в XML, HTML или JSON) и загружает данные ответа сервера напрямую в вызывающий скрипт[1]. Позволяет осуществлять HTTP-запросы к серверу без перезагрузки страницы.
XMLHTTP является важной составляющей технологии AJAX (Asynchronous JavaScript And XML), используется многими сайтами для создания динамичных, быстро реагирующих на запросы пользователя приложений. Например XMLHTTP используется такими сайтами, как Bing Maps, Gmail, Google Maps, Google Suggest, Facebook.
XMLHTTP работает только с файлами, находящимися на том же домене, что и использующая XMLHTTP страница, но существует возможность обойти ограничение. Как и в случае JavaScript, эта возможность обойти ограничение сделана с учётом обеспечения безопасности (cross-site scripting).
Хотя в названии присутствует аббревиатура XML, технология не накладывает ограничений на формат передаваемых данных. Данные можно пересылать как в виде XML, так и в JSON, HTML или просто неструктурированным текстом. Разработчик может самостоятельно создать формат для передачи данных. Однако нужно учитывать, что при пересылке используется текстовый протокол HTTP и потому при использовании метода GET данные должны передаваться в виде текста (то есть бинарные данные следует кодировать, к примеру в base64). При использовании метода POST в кодировании нет необходимости.
История
правитьВпервые был разработан компанией Microsoft, появившись в компоненте Outlook on the web программного продукта Microsoft Exchange Server 2000. Он был назван IXMLHTTPRequest. Позднее наработки были включены в состав MSXML 2.0 в виде объекта ActiveX, доступного через JScript, VBScript или другие скриптовые языки, поддерживающиеся браузером. MSXML 2.0 был включён в состав браузера Internet Explorer 5.
Программисты проекта Mozilla затем разработали совместимую версию, называющуюся nsIXMLHttpRequest в браузер Mozilla 0.6. Доступ к компоненту был реализован через JavaScript-объект, названный XMLHttpRequest. Однако, полной функциональности удалось добиться только в Mozilla 1.0. В дальнейшем поддержка XMLHttpRequest появилась в браузерах Safari 1.2, Opera 8.01 и в других.
Последняя официальная спецификация — версия 1.0 (XMLHttpRequest от 19 декабря 2012 года), которая имеет статус текущего стандарта (Living Standard) и версия 2.0 (XMLHttpRequest Level 2 от 17 января 2012 года), имеющая статус рабочего варианта. Во второй версии вводятся обработчики событий прогресса, поддержка кросс-доменных запросов и работа с бинарными данными.[2]
Методы класса XMLHttpRequest
правитьМетод | Описание |
---|---|
abort() | Отменяет текущий запрос, удаляет все заголовки, ставит текст ответа сервера в null. |
getAllResponseHeaders() | Возвращает полный список HTTP-заголовков в виде строки. Заголовки разделяются знаками переноса (CR+LF). Если флаг ошибки равен true, возвращает пустую строку. Если статус 0 или 1, вызывает ошибку INVALID_STATE_ERR. |
getResponseHeader(headerName) | Возвращает значение указанного заголовка. Если флаг ошибки равен true, возвращает null. Если заголовок не найден, возвращает null. Если статус 0 или 1, вызывает ошибку INVALID_STATE_ERR. |
open(method, URL, async, userName, password) | Определяет метод, URL и другие опциональные параметры запроса; параметр async определяет, происходит ли работа в асинхронном режиме. Последние два параметра необязательны. |
send(content) | Отправляет запрос на сервер. |
setRequestHeader(label, value) | Добавляет HTTP-заголовок к запросу. |
overrideMimeType(mimeType) | Позволяет указать mime-type документа, если сервер его не передал или передал неправильно. Внимание: метод отсутствует в Internet Explorer! |
Свойства класса XMLHttpRequest
правитьСвойство | Тип | Описание |
---|---|---|
onreadystatechange | EventListener | Обработчик события, которое происходит при каждой смене состояния объекта. Имя должно быть записано в нижнем регистре. |
readyState | unsigned short | Текущее состояние объекта (0 — не инициализирован, 1 — открыт, 2 — отправка данных, 3 — получение данных и 4 — данные загружены) |
responseText | DOMString | Текст ответа на запрос. Если состояние не 3 или 4, возвращает пустую строку. |
responseXML | Document | Текст ответа на запрос в виде XML, который затем может быть обработан посредством DOM. Если состояние не 4, возвращает null. |
status | unsigned short | HTTP-статус в виде числа (404 — «Not Found», 200 — «OK» и т. д.) |
statusText | DOMString | Статус в виде строки («Not Found», «OK» и т. д.). Если статус не распознан, браузер пользователя должен вызвать ошибку INVALID_STATE_ERR. |
Ошибки, вызываемые классом XMLHttpRequest
правитьНазвание | Код | Описание |
---|---|---|
SECURITY_ERR | 18 | Вызывается при попытке совершить запрос, запрещённый настройками безопасности в браузере пользователя. |
NETWORK_ERR | 101 | Вызывается при ошибке сети (во время синхронного запроса). |
ABORT_ERR | 102 | Вызывается при прерывании пользователем запроса (во время синхронного запроса). |
Пример использования
правитьПлан работы с объектом XMLHttpRequest можно представить следующим образом:
- Создание экземпляра объекта XMLHttpRequest
- Открытие соединения
- Установка обработчика события (нужно делать после открытия и до отправки в IE)
- Отправка запроса.
Создание экземпляра объекта XMLHttpRequest.
На этой стадии необходима отдельная реализация для разных браузеров. Конструкция создания объекта различается: в IE 5 — IE 6 она реализована через ActiveXObject, а в остальных браузерах (IE 7 и выше, Mozilla, Opera, Chrome, Netscape и Safari) — как встроенный объект типа XMLHttpRequest.
Вызов для ранних версий Internet Explorer выглядит так[3]:
var req = new ActiveXObject("Microsoft.XMLHTTP");
В остальных браузерах:
var req = new XMLHttpRequest();
То есть, для обеспечения кросс-браузерности кода нужно лишь проверять наличие объектов window.XMLHttpRequest и window.ActiveXObject, и, в зависимости от того, какой есть, тот и применять.
В качестве универсального решения предлагается использование такой функции:
function createRequestObject() {
if (typeof XMLHttpRequest === 'undefined') {
XMLHttpRequest = function() {
try { return new ActiveXObject("Msxml2.XMLHTTP.6.0"); }
catch(e) {}
try { return new ActiveXObject("Msxml2.XMLHTTP.3.0"); }
catch(e) {}
try { return new ActiveXObject("Msxml2.XMLHTTP"); }
catch(e) {}
try { return new ActiveXObject("Microsoft.XMLHTTP"); }
catch(e) {}
throw new Error("This browser does not support XMLHttpRequest.");
};
}
return new XMLHttpRequest();
}
Установка обработчика событий, открытие соединения и отправка запросов
Эти вызовы выглядят так:
req.open(<"GET"|"POST"|...>, <url>[, <asyncFlag>[, <user>, <password>]]);
req.onreadystatechange = processReqChange;
Где:
- <"GET"|«POST»|…> — метод запроса. Допускаются: DELETE, GET, HEAD, OPTIONS, POST, PUT.
- <url> — адрес запроса.
- <asyncFlag> — флаг, определяющий, использовать ли асинхронный запрос. По умолчанию установлен в true.
- <user>, <password> — логин и пароль, соответственно. Указываются при необходимости.
После определения всех параметров запроса его остается только отправить. Делается это методом send(). При отправке GET-запроса для версии без ActiveX необходимо указать параметр null, в остальных случаях можно не указывать никаких параметров. Не будет ошибкой, если для GET всегда будет указан параметр null:
req.send(null);
После этого начинает работать вышеуказанный обработчик событий. Он — фактически основная часть программы. В обработчике обычно происходит перехват всех возможных кодов состояния запроса и вызов соответствующих действий, а также перехват возможных ошибок. Пример кода с этими двумя функциями:
var req;
function loadXMLDoc(url)
{
req = null;
if (window.XMLHttpRequest) {
try {
req = new XMLHttpRequest();
} catch (e){}
} else if (window.ActiveXObject) {
try {
req = new ActiveXObject('Msxml2.XMLHTTP');
} catch (e){
try {
req = new ActiveXObject('Microsoft.XMLHTTP');
} catch (e){}
}
}
if (req) {
req.open("GET", url, true);
req.onreadystatechange = processReqChange;
req.send(null);
}
}
function processReqChange()
{
try { // Важно!
// только при состоянии "complete"
if (req.readyState == 4) {
// для статуса "OK"
if (req.status == 200) {
// обработка ответа
} else {
alert("Не удалось получить данные:\n" +
req.statusText);
}
}
}
catch( e ) {
// alert('Ошибка: ' + e.description);
// В связи с багом XMLHttpRequest в Firefox приходится отлавливать ошибку
// Bugzilla Bug 238559 XMLHttpRequest needs a way to report networking errors
// https://bugzilla.mozilla.org/show_bug.cgi?id=238559
}
}
Известные проблемы
правитьЭтот раздел статьи ещё не написан. |
Малый размер буфера при загрузке видео.
См. также
правитьПримечания
править- ↑ XMLHttpRequest object explained by the W3C Working Draft . W3.org. Дата обращения: 14 июля 2009. Архивировано 5 февраля 2012 года.
- ↑ Новые возможности XMLHttpRequest2 . Дата обращения: 30 сентября 2016. Архивировано 7 августа 2016 года.
- ↑ Native XMLHTTPRequest object . Дата обращения: 2 декабря 2009. Архивировано 6 марта 2010 года.
Литература
править- Дейв Крейн, Эрик Паскарелло, Даррен Джеймс. AJAX в действии: технология - Asynchronous JavaScript and XML = Ajax in Action. — М.: «Вильямс», 2006. — С. 640. — ISBN 1-932394-61-3.
- Дари К., Бринзаре Б., Черчез-Тоза Ф., Бусика М. AJAX и PHP: разработка динамических веб-приложений. — СПб.: Символ Плюс, 2006. — С. 336. — ISBN 5-93286-077-4.
Ссылки
править- История XMLHTTP глазами одного из разработчиков // alexhopmann.com (англ.)
- xmlhttprequest.ru: описание, применение, частые проблемы
- Сверхдинамичные веб-интерфейсы // webmascon.com
- Создана рабочая группа по стандартизации XMLHTTPRequest во всех браузерах
Реализация в браузерах:
- Apple Safari и KDE Konqueror (недоступная ссылка)
- Microsoft IXMLHTTPRequest
- Mozilla nsIXMLHttpRequest Архивная копия от 17 октября 2008 на Wayback Machine
- Mozilla XMLHttpRequest object HowTo Архивная копия от 24 февраля 2006 на Wayback Machine
- Mozilla XML Extras
- Opera для компьютеров и для мобильных телефонов