Объект XMLHttpRequest
Введение
Связь между браузером и сервером использует протокол HTTP. Когда пользователь вводит URL-адрес в адресной строке браузера или отправляет контент на сервер через веб-форму, браузер отправляет HTTP-запрос на сервер.
В 1999 году Microsoft выпустила версию 5.0 браузера IE, в которой впервые появилась новая функция: разрешение JavaScript-скриптам инициировать HTTP-запросы к серверу. В то время эта функция оставалась незамеченной и не привлекала широкого внимания до выпуска Gmail в 2004 году и выпуска Google Maps в 2005 году. В феврале 2005 года впервые было официально предложено слово AJAX — это аббревиатура от Asynchronous JavaScript and XML, которая относится к асинхронному обмену данными JavaScript, который получает XML-документы с сервера и извлекает из них данные, а затем обновляет их. соответствующую часть текущей веб-страницы. Нет необходимости обновлять всю страницу. Позже слово AJAX стало синонимом связи HTTP, инициируемой скриптом JavaScript, то есть, если связь инициируется сценарием, ее можно назвать связью AJAX. W3C также опубликовал свой международный стандарт в 2006 году.
В частности, AJAX включает следующие шаги.
- Создайте экземпляр XMLHttpRequest
- сделать HTTP-запрос
- Принимающий сервер возвращает данные
- Обновить веб-данные
Подводя итог, это предложение, AJAX через роднойXMLHttpRequest
Объект отправляет HTTP-запрос, а затем обрабатывает его после получения данных, возвращенных сервером. Теперь сервер возвращает данные в формате JSON, формат XML устарел, но название AJAX стало нарицательным, а буквальное значение исчезло.
XMLHttpRequest
Объекты — это основной интерфейс AJAX для связи между браузером и сервером. Хотя имя имеетXML
а такжеHttp
На самом деле он может использовать различные протоколы (такие какfile
илиftp
), отправка данных в любом формате (включая строковый и двоичный).
XMLHttpRequest
сам по себе является конструктором и может использоваться сnew
команда для создания экземпляра. У него нет никаких параметров.
var xhr = new XMLHttpRequest();
После создания экземпляра вы можете использоватьopen()
Метод указывает некоторые детали установки HTTP-соединения.
xhr.open('GET', 'http://www.example.com/page.php', true);
Приведенный выше код указывает на использование метода GET для установления соединения с указанным URL-адресом сервера. третий параметрtrue
, что указывает на то, что запрос является асинхронным.
Затем укажите функцию обратного вызова для контроля состояния связи (readyState
свойства) меняется.
xhr.onreadystatechange = handleStateChange;
function handleStateChange() {
// ...
}
В приведенном выше коде один разXMLHttpRequest
Когда состояние экземпляра изменяется, вызывается функция слушателя.handleStateChange
последнее использованиеsend()
метод, который фактически делает запрос.
xhr.send(null);
В приведенном выше кодеsend()
Параметрыnull
, что указывает на отсутствие тела данных при отправке запроса. Если вы отправляете POST-запрос, вам нужно указать здесь тело данных.
После получения данных, возвращаемых сервером, AJAX не обновляет всю веб-страницу, а обновляет только соответствующую часть веб-страницы, чтобы не прерывать действия пользователя.
Обратите внимание, что AJAX может отправлять HTTP-запросы только на URL-адреса того же происхождения (с тем же протоколом, доменным именем и портом).
НижеXMLHttpRequest
Полный пример простого использования объектов.
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
// 通信成功时,状态值为4
if (xhr.readyState === 4){
if (xhr.status === 200){
console.log(xhr.responseText);
} else {
console.error(xhr.statusText);
}
}
};
xhr.onerror = function (e) {
console.error(xhr.statusText);
};
xhr.open('GET', '/endpoint', true);
xhr.send(null);
Свойства экземпляра XMLHttpRequest
XMLHttpRequest.readyState
XMLHttpRequest.readyState
Возвращает целое число, представляющее текущее состояние объекта экземпляра. Это свойство доступно только для чтения. Он может возвращать следующие значения.
- 0, что указывает на то, что экземпляр XMLHttpRequest был сгенерирован, но
open()
Метод еще не вызывался. - 1 с указанием
open()
был вызван метод, но экземплярsend()
Метод еще не был вызван, вы все еще можете использовать экземпляр экземпляраsetRequestHeader()
метод, который устанавливает информацию заголовка HTTP-запроса. - 2, указать пример
send()
Метод был вызван, и возвращенные сервером заголовки и коды состояния получены. - 3, что указывает на то, что тело данных (часть тела) принимается с сервера. В этот момент, если экземпляр
responseType
свойство равноtext
или пустая строка,responseText
Атрибут будет содержать часть полученной информации. - 4. Указывает, что данные, возвращенные сервером, были полностью получены или текущий прием не удался.
В процессе связи всякий раз, когда изменяется состояние объекта-экземпляра, егоreadyState
Стоимость имущества изменится. Каждый раз, когда это значение изменяется,readyStateChange
мероприятие.
var xhr = new XMLHttpRequest();
if (xhr.readyState === 4) {
// 请求结束,处理服务器返回的数据
} else {
// 显示提示“加载中……”
}
В приведенном выше кодеxhr.readyState
равный4
, указывая на то, что HTTP-запрос, сделанный сценарием, выполнен. В других случаях это означает, что HTTP-запрос все еще выполняется.
XMLHttpRequest.onreadystatechange
XMLHttpRequest.onreadystatechange
Свойство указывает на функцию прослушивателя.readystatechange
Когда происходит событие (экземплярreadyState
изменение свойства), это свойство будет выполнено.
Кроме того, если вы используете экземплярabort()
метод, завершающий запрос XMLHttpRequest, также вызываетreadyState
изменения свойств, что приводит к вызовуXMLHttpRequest.onreadystatechange
Атрибуты.
Ниже приведен пример.
var xhr = new XMLHttpRequest();
xhr.open( 'GET', 'http://example.com' , true );
xhr.onreadystatechange = function () {
if (xhr.readyState !== 4 || xhr.status !== 200) {
return;
}
console.log(xhr.responseText);
};
xhr.send();
XMLHttpRequest.response
XMLHttpRequest.response
Атрибут представляет тело данных, возвращаемое сервером (т. е. часть тела ответа HTTP). Это может быть любой тип данных, такой как строка, объект, двоичный объект и т. д. Конкретный тип определяетсяXMLHttpRequest.responseType
атрибутивное решение. Свойство XMLHttpRequest.response доступно только для чтения.
Если запрос не удался или данные неполные, это свойство равноnull
. но еслиresponseType
свойство равноtext
или пустая строка, до того как запрос не закончился (readyState
равно 3 этапам),response
Свойства содержат частичные данные, возвращенные сервером.
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
handler(xhr.response);
}
}
XMLHttpRequest.responseType
XMLHttpRequest.responseType
Свойство представляет собой строку, представляющую тип данных, возвращаемых сервером. Это свойство доступно для записи и может быть вызваноopen()
После метода вызовитеsend()
Перед методом установите значение этого свойства, чтобы указать браузеру, как интерпретировать возвращенные данные. еслиresponseType
Установите пустую строку, которая эквивалентна значению по умолчанию.text
.
XMLHttpRequest.responseType
Свойства могут быть равны следующим значениям.
- "" (пустая строка): эквивалентно
text
, указывающее, что сервер возвращает текстовые данные. - "arraybuffer": объект ArrayBuffer, указывающий, что сервер возвращает двоичный массив.
- "blob": объект Blob, указывающий, что сервер возвращает двоичный объект.
- "document": объект документа, указывающий, что сервер возвращает объект документа.
- "json": объект JSON.
- "текст": строка.
Среди вышеперечисленных типовtext
Шрифт подходит для большинства случаев, и с ним удобно работать непосредственно с текстом.document
Этот тип подходит для возврата документов HTML/XML, а это означает, что для тех веб-сайтов, которые открывают CORS, вы можете напрямую использовать Ajax для обхода веб-страницы, а затем напрямую выполнять операции DOM с захваченными данными без разбора строки HTML.blob
Тип подходит для чтения двоичных данных, таких как файлы изображений.
var xhr = new XMLHttpRequest();
xhr.open('GET', '/path/to/image.png', true);
xhr.responseType = 'blob';
xhr.onload = function(e) {
if (this.status === 200) {
var blob = new Blob([xhr.response], {type: 'image/png'});
// 或者
var blob = xhr.response;
}
};
xhr.send();
Если это свойство установлено вArrayBuffer
, вы можете обрабатывать двоичные данные как массив.
var xhr = new XMLHttpRequest();
xhr.open('GET', '/path/to/image.png', true);
xhr.responseType = 'arraybuffer';
xhr.onload = function(e) {
var uInt8Array = new Uint8Array(this.response);
for (var i = 0, len = uInt8Array.length; i < len; ++i) {
// var byte = uInt8Array[i];
}
};
xhr.send();
Если это свойство установлено вjson
, браузер автоматически вызовет возвращенные данныеJSON.parse()
метод. То есть изxhr.response
свойства (обратите внимание, неxhr.responseText
свойство) вместо текста вы получаете объект JSON.
XMLHttpRequest.responseText
XMLHttpRequest.responseText
Свойство возвращает строку, полученную от сервера, это свойство доступно только для чтения. Это свойство не будет содержать полные данные, пока не будет получен HTTP-запрос.
var xhr = new XMLHttpRequest();
xhr.open('GET', '/server', true);
xhr.responseType = 'text';
xhr.onload = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
console.log(xhr.responseText);
}
};
xhr.send(null);
XMLHttpRequest.responseXML
XMLHttpRequest.responseXML
Свойство возвращает объект документа HTML или XML, полученный от сервера, и доступен только для чтения. Если запрос был неудачным или полученные данные не удалось проанализировать как XML или HTML, этот атрибут равенnull
.
Условием для того, чтобы этот атрибут вступил в силу, является то, что ответ HTTPContent-Type
Информация о головке равнаtext/xml
илиapplication/xml
. Для этого необходимо, чтобы перед отправкой запросаXMLHttpRequest.responseType
свойство, которое должно быть установленоdocument
. если ответ HTTPContent-Type
информация заголовка не равнаtext/xml
а такжеapplication/xml
, но хочуresponseXML
Получить данные (то есть разобрать данные по формату DOM), затем нужно вручную вызватьXMLHttpRequest.overrideMimeType()
метод принудительного разбора XML.
Данные, полученные с помощью этого свойства, представляют собой непосредственно анализируемое дерево DOM документа.
var xhr = new XMLHttpRequest();
xhr.open('GET', '/server', true);
xhr.responseType = 'document';
xhr.overrideMimeType('text/xml');
xhr.onload = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
console.log(xhr.responseXML);
}
};
xhr.send(null);
XMLHttpRequest.responseURL
XMLHttpRequest.responseURL
Свойство представляет собой строку, представляющую URL-адрес сервера, отправляющего данные.
var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://example.com/test', true);
xhr.onload = function () {
// 返回 http://example.com/test
console.log(xhr.responseURL);
};
xhr.send(null);
Обратите внимание, что значение этого свойства такое же, какopen()
URL-адрес запроса, указанный методом, не обязательно совпадает. Если на стороне сервера происходит переход, это свойство возвращает последний URL-адрес, фактически вернувший данные. Кроме того, если исходный URL-адрес содержал привязку (фрагмент), это свойство удаляет привязку.
XMLHttpRequest.status, XMLHttpRequest.statusText
XMLHttpRequest.status
Свойство возвращает целое число, представляющее код состояния HTTP, которым ответил сервер. Вообще говоря, если связь успешна, этот код состояния равен 200; если сервер не возвращает код состояния, то это свойство по умолчанию равно 200. Прежде чем сделать запрос, имущество0
. Это свойство доступно только для чтения.
- 200, ок, доступ нормальный
- 301, переехал навсегда
- 302, Временно переехал
- 304, не изменено, не изменено
- 307, Временная переадресация, временная переадресация
- 401, Неавторизованный, неавторизованный
- 403, Запрещено, Запрещено
- 404, Not Found, указанный URL не найден
- 500, Внутренняя ошибка сервера, произошла ошибка сервера
По сути, есть только коды состояния 2xx и 304, указывающие на то, что сервер возвращает нормальный статус.
if (xhr.readyState === 4) {
if ( (xhr.status >= 200 && xhr.status < 300)
|| (xhr.status === 304) ) {
// 处理服务器的返回数据
} else {
// 出错
}
}
XMLHttpRequest.statusText
Свойство возвращает строку, представляющую запрос состояния, отправленный сервером. отличный отstatus
свойство, которое содержит всю информацию о состоянии, такую как «ОК» и «Не найдено». до того, как запрос будет отправлен (т.е. вызовopen()
Перед методом) значение свойства является пустой строкой; если сервер не возвращает приглашение состояния, значение по умолчанию это атрибут «ОК». Это свойство только для чтения.
XMLHttpRequest.timeout, XMLHttpRequestEventTarget.ontimeout
XMLHttpRequest.timeout
Свойство возвращает целое число, указывающее количество миллисекунд, по истечении которых запрос автоматически завершится, если результата по-прежнему нет. Если это свойство равно 0, это означает, что ограничения по времени нет.
XMLHttpRequestEventTarget.ontimeout
Свойство используется для установки функции прослушивателя, которая будет выполняться, если произойдет событие тайм-аута.
Ниже приведен пример.
var xhr = new XMLHttpRequest();
var url = '/server';
xhr.ontimeout = function () {
console.error('The request for ' + url + ' timed out.');
};
xhr.onload = function() {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
// 处理服务器返回的数据
} else {
console.error(xhr.statusText);
}
}
};
xhr.open('GET', url, true);
// 指定 10 秒钟超时
xhr.timeout = 10 * 1000;
xhr.send(null);
свойство прослушивателя событий
Объект XMLHttpRequest может указывать функции прослушивателя для следующих событий.
- XMLHttpRequest.onloadstart: функция прослушивания события loadstart (запрос HTTP отправлен)
- XMLHttpRequest.onprogress: функция прослушивания для события прогресса (отправка и загрузка данных)
- XMLHttpRequest.onabort: событие прерывания (запрос прерван, например, вызванный пользователем
abort()
метод) функция слушателя - XMLHttpRequest.onerror: функция прослушивания события ошибки (сбой запроса)
- XMLHttpRequest.onload: функция прослушивания события загрузки (запрос выполнен успешно)
- XMLHttpRequest.ontimeout: функция прослушивания события тайм-аута (указанный пользователем лимит времени превышен, и запрос не был выполнен)
- XMLHttpRequest.onloadend: функция прослушивания события loadend (запрос выполнен независимо от успеха или неудачи)
Ниже приведен пример.
xhr.onload = function() {
var responseText = xhr.responseText;
console.log(responseText);
// process the response.
};
xhr.onabort = function () {
console.log('The request was aborted');
};
xhr.onprogress = function (event) {
console.log(event.loaded);
console.log(event.total);
};
xhr.onerror = function() {
console.log('There was an error!');
};
progress
Функция прослушивателя событий имеет параметр объекта события, который имеет три свойства:loaded
свойство возвращает количество данных, которые были переданы,total
свойство возвращает общий объем данных,lengthComputable
Свойство возвращает логическое значение, указывающее, можно ли рассчитать ход загрузки. Из всех этих функций слушателя толькоprogress
Функция слушателя события имеет параметры, а другие функции не имеют параметров.
Обратите внимание, что в случае сетевой ошибки (например, если сервер недоступен),onerror
Событие не может получить сообщение об ошибке. То есть может не быть объекта ошибки, поэтому он может отображать только сообщение об ошибке.
XMLHttpRequest.withCredentials
XMLHttpRequest.withCredentials
Атрибут представляет собой логическое значение, указывающее, будет ли информация о пользователе (такая как файлы cookie и информация заголовка HTTP аутентификации) включаться в запрос во время междоменных запросов.false
, то есть кexample.com
При создании кросс-оригинального запроса он не отправляетсяexample.com
Файлы cookie, установленные на этом компьютере (если есть).
Если вам нужно отправлять файлы cookie для междоменных запросов AJAX, вам необходимоwithCredentials
свойство установлено наtrue
. Обратите внимание, что для гомологичных запросов не требуется устанавливать это свойство.
var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://example.com/', true);
xhr.withCredentials = true;
xhr.send(null);
Чтобы это свойство вступило в силу, сервер должен явно вернутьAccess-Control-Allow-Credentials
эта информация заголовка.
Access-Control-Allow-Credentials: true
withCredentials
Если атрибут включен, междоменный запрос не только отправит файл cookie, но и установит файл cookie, указанный удаленным хостом. Верно и обратное, еслиwithCredentials
Если атрибут не включен, браузер будет игнорировать междоменный запрос AJAX, даже если он явно просит браузер установить файл cookie.
Обратите внимание, что сценарии всегда придерживаются политики одного и того же источника и не могут быть загружены изdocument.cookie
Или прочитайте междоменный файл cookie в информации заголовка HTTP-ответа,withCredentials
Свойства на это не влияют.
XMLHttpRequest.upload
XMLHttpRequest может не только отправлять запросы, но и файлы, то есть загружать файлы AJAX. После отправки файла черезXMLHttpRequest.upload
Свойства могут получить объект, и, наблюдая за этим объектом, вы можете узнать о ходе загрузки. Основной метод — отслеживать различные события этого объекта: loadstart, loadend, load, abort, error, progress, timeout.
Предположим, есть<progress>
элемент.
<progress min="0" max="100" value="0">0% complete</progress>
Когда файл загружен, даupload
назначение атрибутаprogress
Функция прослушивания событий, вы можете получить ход загрузки.
function upload(blobOrFile) {
var xhr = new XMLHttpRequest();
xhr.open('POST', '/server', true);
xhr.onload = function (e) {};
var progressBar = document.querySelector('progress');
xhr.upload.onprogress = function (e) {
if (e.lengthComputable) {
progressBar.value = (e.loaded / e.total) * 100;
// 兼容不支持 <progress> 元素的老式浏览器
progressBar.textContent = progressBar.value;
}
};
xhr.send(blobOrFile);
}
upload(new Blob(['hello world'], {type: 'text/plain'}));
Методы экземпляра XMLHttpRequest
XMLHttpRequest.open()
XMLHttpRequest.open()
Этот метод используется для указания параметров HTTP-запроса или для инициализации объекта экземпляра XMLHttpRequest. Он может принимать в общей сложности пять параметров.
void open(
string method,
string url,
optional boolean async,
optional string user,
optional string password
);
-
method
: представляет метод HTTP-глагола, напримерGET
,POST
,PUT
,DELETE
,HEAD
Ждать. -
url
: указывает запрос на отправку целевого URL. -
async
: логическое значение, указывающее, является ли запрос асинхронным, по умолчаниюtrue
. Если установленоfalse
,ноsend()
Метод не перейдет к следующему шагу, пока не получит результат, возвращенный сервером. Этот параметр является необязательным. Поскольку синхронные запросы AJAX приводят к тому, что браузер перестает отвечать на запросы, многие браузеры запретили его использование в основном потоке и разрешили использовать его только в Worker. Поэтому этот параметр легко не должен быть установлен наfalse
. -
user
: указывает имя пользователя, используемое для аутентификации, по умолчанию — пустая строка. Этот параметр является необязательным. -
password
: указывает пароль, используемый для аутентификации, по умолчанию — пустая строка. Этот параметр является необязательным.
Обратите внимание, что если вы использовалиopen()
AJAX-запрос метода, повторное использование этого метода эквивалентно вызовуabort()
, который завершает запрос.
Ниже приведен пример отправки POST-запроса.
var xhr = new XMLHttpRequest();
xhr.open('POST', encodeURI('someURL'));
XMLHttpRequest.send()
XMLHttpRequest.send()
метод используется для фактического выполнения HTTP-запроса. Его параметры необязательны. Если нет параметров, это означает, что HTTP-запрос имеет только один URL и не имеет тела данных. Типичный пример — GET-запрос, если он имеет параметры, это означает, что помимо информации заголовка, он также содержит информацию, содержащую определенные данные body, типичным примером является POST-запрос.
Ниже приведен пример GET-запроса.
var xhr = new XMLHttpRequest();
xhr.open('GET',
'http://www.example.com/?id=' + encodeURIComponent(id),
true
);
xhr.send(null);
В приведенном выше кодеGET
Параметры запроса, добавленные к URL-адресу в виде строки запроса.
Ниже приведен пример отправки POST-запроса.
var xhr = new XMLHttpRequest();
var data = 'email='
+ encodeURIComponent(email)
+ '&password='
+ encodeURIComponent(password);
xhr.open('POST', 'http://www.example.com', true);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.send(data);
Обратите внимание, что все события прослушивателя XMLHttpRequest должныsend()
Устанавливается перед вызовом метода.
send
Параметр метода — это данные для отправки. В качестве его параметров могут использоваться данные в различных форматах.
void send();
void send(ArrayBufferView data);
void send(Blob data);
void send(Document data);
void send(String data);
void send(FormData data);
еслиsend()
Отправьте объект DOM, данные будут сериализованы перед отправкой. При отправке двоичных данных лучше отправитьArrayBufferView
илиBlob
объект, что позволяет загружать файлы через Ajax.
Ниже приведен пример отправки данных формы.FormData
Объекты можно использовать для создания данных формы.
var formData = new FormData();
formData.append('username', '张三');
formData.append('email', 'zhangsan@example.com');
formData.append('birthDate', 1940);
var xhr = new XMLHttpRequest();
xhr.open('POST', '/register');
xhr.send(formData);
В приведенном выше кодеFormData
объект создает данные формы, а затем используетsend()
способ отправки. Это имеет тот же эффект, что и отправка данных формы ниже.
<form id='registration' name='registration' action='/register'>
<input type='text' name='username' value='张三'>
<input type='email' name='email' value='zhangsan@example.com'>
<input type='number' name='birthDate' value='1940'>
<input type='submit' onclick='return sendForm(this.form);'>
</form>
В следующем примере используетсяFormData
Объект обрабатывает данные формы перед их отправкой.
function sendForm(form) {
var formData = new FormData(form);
formData.append('csrf', 'e69a18d7db1286040586e6da1950128c');
var xhr = new XMLHttpRequest();
xhr.open('POST', form.action, true);
xhr.onload = function() {
// ...
};
xhr.send(formData);
return false;
}
var form = document.querySelector('#registration');
sendForm(form);
XMLHttpRequest.setRequestHeader()
XMLHttpRequest.setRequestHeader()
Этот метод используется для установки информации заголовка HTTP-запроса, отправляемого браузером. Метод должен бытьopen()
Позже,send()
звонил раньше. Если этот метод вызывается несколько раз для установки одного и того же поля, значения каждого вызова будут объединены в одно значение и отправлены.
Метод принимает два параметра. Первый параметр — это строка, представляющая имя поля информации заголовка, а второй параметр — это значение поля.
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.setRequestHeader('Content-Length', JSON.stringify(data).length);
xhr.send(JSON.stringify(data));
Приведенный выше код сначала устанавливает информацию заголовкаContent-Type
, что означает отправку данных в формате JSON, затем установитеContent-Length
, указав длину данных; наконец, отправьте данные JSON.
XMLHttpRequest.overrideMimeType()
XMLHttpRequest.overrideMimeType()
Этот метод используется для указания типа MIME, переопределяя реальный тип MIME, возвращаемый сервером, чтобы браузер мог обрабатывать его по-другому. Например, тип данных, возвращаемый сервером,text/xml
, по разным причинам браузер не может выполнить синтаксический анализ и сообщает об ошибке, а данные не могут быть получены в настоящее время. Чтобы получить необработанные данные, мы можем изменить тип MIME наtext/plain
, чтобы браузер не разбирал его автоматически, чтобы мы могли получить исходный текст.
xhr.overrideMimeType('text/plain')
Обратите внимание, что этот метод должен бытьsend()
метод вызывается раньше.
Изменение типа данных, возвращаемых сервером, не является методом, который следует использовать в обычных обстоятельствах. Если вы хотите, чтобы сервер возвращал указанный тип данных, вы можете использоватьresponseType
Атрибут сообщает серверу, как в примере ниже. Используйте только в том случае, если сервер не может вернуть определенный тип данныхoverrideMimeType()
метод.
var xhr = new XMLHttpRequest();
xhr.onload = function(e) {
var arraybuffer = xhr.response;
// ...
}
xhr.open('GET', url);
xhr.responseType = 'arraybuffer';
xhr.send();
XMLHttpRequest.getResponseHeader()
XMLHttpRequest.getResponseHeader()
Метод возвращает значение указанного поля в информации заголовка HTTP.Если сервер не получил ответа или указанного поля не существует, возвращаетnull
. Аргументы этого метода не чувствительны к регистру.
function getHeaderTime() {
console.log(this.getResponseHeader("Last-Modified"));
}
var xhr = new XMLHttpRequest();
xhr.open('HEAD', 'yourpage.html');
xhr.onload = getHeaderTime;
xhr.send();
Если есть несколько полей с одинаковым именем, их значения будут объединены в строку, и каждое поле будет разделено «запятой+пробелом».
XMLHttpRequest.getAllResponseHeaders()
XMLHttpRequest.getAllResponseHeaders()
Метод возвращает строку, представляющую все заголовки HTTP, отправленные сервером. Формат представляет собой строку, используемую между каждой информацией заголовка.CRLF
Разделение (возврат каретки + перевод строки), если ответ от сервера не получен, это свойствоnull
. Если возникает сетевая ошибка, это свойство представляет собой пустую строку.
var xhr = new XMLHttpRequest();
xhr.open('GET', 'foo.txt', true);
xhr.send();
xhr.onreadystatechange = function () {
if (this.readyState === 4) {
var headers = xhr.getAllResponseHeaders();
}
}
Приведенный выше код используется для получения всей информации заголовка, возвращаемой сервером. Это может быть строка, подобная следующей.
date: Fri, 08 Dec 2017 21:04:30 GMT\r\n
content-encoding: gzip\r\n
x-content-type-options: nosniff\r\n
server: meinheld/0.6.1\r\n
x-frame-options: DENY\r\n
content-type: text/html; charset=utf-8\r\n
connection: keep-alive\r\n
strict-transport-security: max-age=63072000\r\n
vary: Cookie, Accept-Encoding\r\n
content-length: 6502\r\n
x-xss-protection: 1; mode=block\r\n
Затем обработайте эту строку.
var arr = headers.trim().split(/[\r\n]+/);
var headerMap = {};
arr.forEach(function (line) {
var parts = line.split(': ');
var header = parts.shift();
var value = parts.join(': ');
headerMap[header] = value;
});
headerMap['content-length'] // "6502"
XMLHttpRequest.abort()
XMLHttpRequest.abort()
Этот метод используется для завершения сделанного HTTP-запроса. После вызова этого методаreadyState
собственность становится4
,status
собственность становится0
.
var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://www.example.com/page.php', true);
setTimeout(function () {
if (xhr) {
xhr.abort();
xhr = null;
}
}, 5000);
Приведенный выше код завершает запрос AJAX через 5 секунд после его отправки.
События для экземпляров XMLHttpRequest
событие readyStateChange
readyState
При изменении значения свойства запускается событие readyStateChange.
мы можем пройтиonReadyStateChange
Атрибут определяет функцию прослушивателя этого события и по-разному обрабатывает разные состояния. особенно когда государство становится4
Когда связь успешна, функция обратного вызова может обрабатывать данные, отправленные обратно сервером.
событие прогресса
При загрузке файла сам объект экземпляра XMLHttpRequest иupload
атрибут, естьprogress
событие, которое будет постоянно возвращать ход загрузки.
var xhr = new XMLHttpRequest();
function updateProgress (oEvent) {
if (oEvent.lengthComputable) {
var percentComplete = oEvent.loaded / oEvent.total;
} else {
console.log('无法计算进展');
}
}
xhr.addEventListener('progress', updateProgress);
xhr.open();
событие загрузки, событие ошибки, событие прерывания
Событие загрузки указывает на то, что данные с сервера были получены, событие ошибки указывает на то, что запрос был выполнен неправильно, а событие прерывания указывает на то, что запрос был прерван (например, пользователь отменяет запрос).
var xhr = new XMLHttpRequest();
xhr.addEventListener('load', transferComplete);
xhr.addEventListener('error', transferFailed);
xhr.addEventListener('abort', transferCanceled);
xhr.open();
function transferComplete() {
console.log('数据接收完毕');
}
function transferFailed() {
console.log('数据接收出错');
}
function transferCanceled() {
console.log('用户取消接收');
}
событие завершения загрузки
abort
,load
а такжеerror
Эти три мероприятия будут сопровождатьсяloadend
Событие, указывающее на завершение запроса, но неизвестно, был ли он успешным.
xhr.addEventListener('loadend', loadEnd);
function loadEnd(e) {
console.log('请求结束,状态未知');
}
событие тайм-аута
Если сервер не вернул результат по истечении указанного времени, будет запущено событие тайм-аута Конкретные примеры см.timeout
Раздел свойств.
Navigator.sendBeacon()
Когда пользователь удаляет веб-страницу, иногда необходимо отправить некоторые данные на сервер. Естественный способ состоит в том, чтобыunload
событие илиbeforeunload
Внутри функции прослушивателя событий используйтеXMLHttpRequest
Объект отправляет данные. Однако это не очень надежно, посколькуXMLHttpRequest
Объект отправляется асинхронно, и, вероятно, когда он будет отправлен, страница уже будет выгружена, что приведет к отмене или сбою отправки.
Решениеunload
На всякий случай добавьте несколько трудоемких операций синхронизации. Это дает достаточно времени для успешной отправки асинхронного AJAX.
function log() {
let xhr = new XMLHttpRequest();
xhr.open('post', '/log', true);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.send('foo=bar');
}
window.addEventListener('unload', function(event) {
log();
// a time-consuming operation
for (let i = 1; i < 10000; i++) {
for (let m = 1; m < 10000; m++) { continue; }
}
});
В приведенном выше коде применяется двойной цикл, который продлеваетunload
Время выполнения события, благодаря которому асинхронный AJAX может быть успешно отправлен.
Подобные также могут быть использованыsetTimeout
. Ниже приведен пример отслеживания кликов пользователей.
// HTML 代码如下
// <a id="target" href="https://baidu.com">click</a>
const clickTime = 350;
const theLink = document.getElementById('target');
function log() {
let xhr = new XMLHttpRequest();
xhr.open('post', '/log', true);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.send('foo=bar');
}
theLink.addEventListener('click', function (event) {
event.preventDefault();
log();
setTimeout(function () {
window.location.href = theLink.getAttribute('href');
}, clickTime);
});
Используйте приведенный выше кодsetTimeout
, задерживается на 350 миллисекунд перед переходом на страницу, что дает асинхронному AJAX время для выполнения.
Общая проблема этих практик заключается в том, что время выгрузки резко увеличивается, загрузка последующих страниц задерживается, а взаимодействие с пользователем ухудшается.
Чтобы решить эту проблему, браузеры представилиNavigator.sendBeacon()
метод. Этот метод по-прежнему отправляет запрос асинхронно, но запрос отделяется от потока текущей страницы как задача процесса браузера, поэтому гарантируется, что данные будут отправлены без задержки процесса удаления.
window.addEventListener('unload', logData, false);
function logData() {
navigator.sendBeacon('/log', analyticsData);
}
Navigator.sendBeacon
Метод принимает два параметра, первый параметр — это URL-адрес целевого сервера, а второй параметр — это отправляемые данные (необязательно), которые могут быть любого типа (строка, объект формы, двоичный объект и т. д.).
navigator.sendBeacon(url, data)
Возвращаемое значение этого метода является логическим значением, а успешно отправленные данныеtrue
, иначеfalse
.
Метод HTTP для отправки данных с помощью этого метода — POST, который может быть междоменным, подобно данным отправки формы. Он не может указать функцию обратного вызова.
Ниже приведен пример.
// HTML 代码如下
// <body onload="analytics('start')" onunload="analytics('end')">
function analytics(state) {
if (!navigator.sendBeacon) return;
var URL = 'http://example.com/analytics';
var data = 'state=' + state + '&location=' + window.location;
navigator.sendBeacon(URL, data);
}