JavaScript интерфейс XMLHttpRequest

Описание интерфейса

Интерфейс XMLHttpRequest это интерфейс, который предоставляет функциональность для обмена данными между клиентом и сервером, он дает возможность получения данных по URL без необходимости полного обновления страницы. Интерфейс XMLHttpRequest широко используется в асинхронных запросах AJAX (от англ. Asynchronous JavaScript and XML — «асинхронный JavaScript и XML»), что позволяет конкретной странице обновлять только её часть, не нарушая при этом работу пользователя. Кроме того, XMLHttpRequest имеет широкое использование при разработке одностраничных приложений (англ. single page application, SPA).

Несмотря на название, XMLHttpRequest работает с текстом, JSON и двоичными данными. Доступ к ресурсам подчиняется правилам источника и CORS; поддержку FTP современный браузер не предоставляет. Для новых задач чаще используют метод fetch(), который возвращает Promise; XMLHttpRequest остаётся полезен для отслеживания прогресса выгрузки и поддержки существующего кода.

Синтаксис

JavaScript
const request = new XMLHttpRequest();

При вызове конструктора возвращается новый объект XMLHttpRequest. Объект должен быть подготовлен по крайней мере вызовом метода open(), чтобы инициализировать его перед вызовом send() для отправки запроса на сервер.

Константы

Следующие константы определяют возможные значения свойства readyState. Они доступны как статические свойства конструктора (XMLHttpRequest.DONE) и через экземпляр (xhr.DONE).

Константы состояний XMLHttpRequest
Значение Константа Описание
0 UNSENT Объект XMLHttpRequest был создан, метод open() объекта не вызывался.
1 OPENED Метод open() объекта был вызван. Во время этого состояния заголовки запросов могут быть установлены с помощью метода setRequestHeader() и может быть вызван метод send(), который инициирует отправку запроса.
2 HEADERS_RECEIVED Метод send() объекта был вызван, заголовки и статус ответа получены и доступны.
3 LOADING Происходит загрузка тела ответа сервера. Если значение свойства responseType соответствует значению "text" или пустой строке, то значение свойства responseText будет содержать частичные данные.
4 DONE Операция завершена. Это может означать, что передача данных была завершена успешно или не удалась.

Свойства интерфейса

Свойства экземпляра XMLHttpRequest
Свойство Описание
onreadystatechange Обработчик события readystatechange: функция или null. Событие может повторяться в LOADING без изменения состояния; переход в UNSENT после отмены не сопровождается отдельным таким событием.
readyState Возвращает число от 0 до 4 — состояние объекта XMLHttpRequest. Только для чтения.
response Свойство возвращает содержимое тела ответа в виде ArrayBuffer, Blob, Document, значения, полученного из JSON, или строки в зависимости от значения свойства responseType запроса. Только для чтения.
responseText Возвращает строку с текстом ответа. До получения тела ответа и при ошибке запроса возвращается пустая строка. Если responseType не равен "" или "text", обращение вызывает исключение InvalidStateError.
responseType Задает или возвращает перечисляемое строковое значение, указывающее тип данных, содержащихся в ответе: "", "arraybuffer", "blob", "document", "json" или "text".
responseURL Возвращает сериализованный URL ответа (после перенаправлений) или пустую строку, если URL отсутствует. Только для чтения.
responseXML Возвращает документ (Document), содержащий HTML или XML, полученный запросом, или значение null, если запрос был неудачным, еще не был завершен, или если данные не могут быть проанализированы как XML или HTML. Если responseType не равен "" или "document", обращение вызывает исключение InvalidStateError.
status Возвращает числовой код состояния HTTP-ответа, полученный от сервера, или 0, если ответ ещё не получен или произошла сетевая ошибка. Только для чтения.
statusText Возвращает строку с текстом состояния HTTP-ответа (например, "OK") или пустую строку. Только для чтения.
timeout Соответствует количеству миллисекунд, которые может занять запрос перед автоматическим завершением (предельное время ожидания ответа). Значение 0 (по умолчанию) означает отсутствие ограничения.
upload Свойство возвращает объект XMLHttpRequestUpload, который позволяет регистрировать обработчики событий для отслеживания процесса выгрузки тела HTTP-запроса. Только для чтения.
withCredentials Логическое значение, которое определяет, передаются ли учётные данные (cookie, заголовки HTTP-аутентификации и клиентские TLS-сертификаты) при запросе к другому источнику по CORS (англ. Cross-Origin Resource Sharing — «совместное использование ресурсов между разными источниками») и сохраняются ли cookie из такого ответа. По умолчанию false.

Методы интерфейса

Методы экземпляра XMLHttpRequest
Метод Описание
abort() Позволяет прервать запрос, если он уже был отправлен. Возвращает undefined.
getAllResponseHeaders() Возвращает все доступные заголовки ответа одной строкой; каждая пара «имя: значение» завершается последовательностью CRLF. Если ответ ещё не получен, возвращается пустая строка.
getResponseHeader() Возвращает строку, содержащую текст указанного заголовка, или null, если ответ еще не был получен, или заголовок не существует в ответе.
open() Позволяет инициализировать только что созданный запрос, или повторно инициализировать существующий запрос.
overrideMimeType() Позволяет переопределить MIME-тип, возвращаемый сервером: задает тип, который будет использован при интерпретации данных ответа вместо указанного сервером. Обычно вызывается до send(), но допустим и в состоянии HEADERS_RECEIVED. В LOADING и DONE вызывает InvalidStateError.
send() Позволяет отправить запрос на сервер, при необходимости с телом запроса.
setRequestHeader() Задает значение заголовка HTTP-запроса. Вызывается после open() и до send().

События

Собственное событие XMLHttpRequest — readystatechange; его обрабатывает свойство onreadystatechange. Остальные обработчики событий ниже — свойства экземпляра, унаследованные от XMLHttpRequestEventTarget; они принимают функцию или null. Отдельных статей о них пока нет.

События XMLHttpRequest
Обработчик Назначение
onloadstart Начало запроса (событие loadstart).
onprogress Получение части ответа (событие progress); объект ProgressEvent сообщает loaded, total и lengthComputable.
onabort Отмена запроса (событие abort).
onerror Сетевая ошибка (событие error); HTTP-ответ с кодом ошибки сам по себе не вызывает его.
onload Передача завершена (событие load); проверяйте status для оценки HTTP-результата.
ontimeout Превышено время ожидания timeout (событие timeout).
onloadend Завершение после успеха, отмены, ошибки или тайм-аута (событие loadend).

Методы addEventListener(), removeEventListener() и dispatchEvent() наследуются от EventTarget.

На прототипе интерфейса определено символьное свойство Symbol.toStringTag со строковым значением "XMLHttpRequest"; оно используется при строковом представлении через Object.prototype.toString.

Спецификация

XMLHttpRequest Standard.

Ответ сервера и ошибки запроса

Сохраните весь пример и откройте через HTTP-сервер. Рядом создайте user-profile.json с содержимым { "phone": "+7 800 555-35-35" }. Переименуйте файл для ответа 404; задержите ответ сервера для проверки отмены и тайм-аута.

Исходный код для изучения. Запуск на этой странице недоступен.

index.html
HTML
<button id="load" type="button">Загрузить профиль</button>
<button id="cancel" type="button">Отменить запрос</button>
<pre id="result" aria-live="polite"></pre>
main.js
JavaScript
const result = document.querySelector('#result')
const loadButton = document.querySelector('#load')
let request
loadButton.addEventListener('click', () => {
    const xhr = new XMLHttpRequest()
    request = xhr
    loadButton.disabled = true
    result.textContent = 'Загрузка…'
    xhr.open('GET', 'user-profile.json')
    xhr.timeout = 5000
    xhr.responseType = 'json'
    xhr.onload = () => {
        if (xhr.status < 200 || xhr.status >= 300) {
            result.textContent = 'Ошибка HTTP: ' + xhr.status
        } else if (!xhr.response || typeof xhr.response.phone !== 'string') {
            result.textContent = 'Ожидался JSON-объект со строковым полем phone'
        } else {
            result.textContent = 'Телефон: ' + xhr.response.phone
        }
    }
    xhr.onerror = () => {
        result.textContent = 'Сетевая ошибка или запрет CORS'
    }
    xhr.ontimeout = () => {
        result.textContent = 'Превышено время ожидания'
    }
    xhr.onabort = () => {
        result.textContent = 'Запрос отменён'
    }
    xhr.onloadend = () => {
        loadButton.disabled = false
        request = null
    }
    xhr.send()
})
document.querySelector('#cancel').addEventListener('click', () => request?.abort())