JavaScript интерфейс XMLHttpRequest
Описание интерфейса
Интерфейс XMLHttpRequest это интерфейс, который предоставляет функциональность для обмена данными между
клиентом и сервером, он дает возможность получения данных по URL без необходимости полного обновления страницы.
Интерфейс XMLHttpRequest широко используется в асинхронных запросах AJAX (от англ.
Asynchronous JavaScript and XML — «асинхронный JavaScript и XML»), что позволяет конкретной
странице обновлять только её часть, не нарушая при этом работу пользователя. Кроме того,
XMLHttpRequest имеет широкое использование при разработке одностраничных приложений (англ.
single page application, SPA).
Несмотря на название, XMLHttpRequest работает с текстом, JSON и двоичными данными. Доступ к ресурсам
подчиняется правилам источника и CORS; поддержку FTP современный браузер не предоставляет. Для новых задач чаще
используют метод fetch(), который возвращает Promise; XMLHttpRequest остаётся
полезен для отслеживания прогресса выгрузки и поддержки существующего кода.
Синтаксис
const request = new XMLHttpRequest();
При вызове конструктора возвращается новый объект XMLHttpRequest. Объект должен быть подготовлен по
крайней мере вызовом метода
open(), чтобы инициализировать его перед вызовом
send()
для отправки запроса на сервер.
Константы
Следующие константы определяют возможные значения свойства
readyState. Они доступны как статические свойства конструктора (XMLHttpRequest.DONE) и через экземпляр
(xhr.DONE).
| Значение | Константа | Описание |
|---|---|---|
0 |
UNSENT |
Объект XMLHttpRequest был создан, метод
open()
объекта не вызывался.
|
1 |
OPENED |
Метод
open()
объекта был вызван. Во время этого состояния заголовки запросов могут быть установлены с помощью метода
setRequestHeader()
и может быть вызван метод
send(), который инициирует отправку запроса.
|
2 |
HEADERS_RECEIVED |
Метод
send()
объекта был вызван, заголовки и статус ответа получены и доступны.
|
3 |
LOADING |
Происходит загрузка тела ответа сервера. Если значение свойства
responseType
соответствует значению "text" или пустой строке, то значение свойства
responseText
будет содержать частичные данные.
|
4 |
DONE |
Операция завершена. Это может означать, что передача данных была завершена успешно или не удалась. |
Свойства интерфейса
| Свойство | Описание |
|---|---|
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.
|
Методы интерфейса
| Метод | Описание |
|---|---|
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. Отдельных статей о них пока нет.
| Обработчик | Назначение |
|---|---|
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.
Спецификация
Ответ сервера и ошибки запроса
Сохраните весь пример и откройте через HTTP-сервер. Рядом создайте user-profile.json с содержимым { "phone": "+7 800 555-35-35" }. Переименуйте файл для ответа 404; задержите ответ сервера для проверки отмены и тайм-аута.
Исходный код для изучения. Запуск на этой странице недоступен.
index.html
<button id="load" type="button">Загрузить профиль</button>
<button id="cancel" type="button">Отменить запрос</button>
<pre id="result" aria-live="polite"></pre>
main.js
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())