Объекты XMLHttpRequest или то, что мы называем (XHR), используются для взаимодействия с серверами. Это позволяет веб-странице обновлять только часть страницы, не нарушая того, что делает пользователь.

некоторые из самых ранних экземпляров этого типа запросов использовались в почтовом ящике Gmail. Это работало каждые 20–30 секунд, новый запрос отправлялся, чтобы узнать, есть ли у вас новая почта.

Было довольно революционно видеть обновленное электронное письмо без необходимости обновлять страницу.

Концепция объекта XMLHttpRequest была первоначально создана разработчиками Outlook Web Access для Microsoft Exchange Server 2000. Это базовая технология, лежащая в основе шаблона, который мы знаем как «Ajax».

Интерфейс под названием IXMLHTTPRequest был разработан и реализован во второй версии библиотеки MSXML (Microsoft XML Core Services) с использованием этой концепции.

Вторая версия библиотеки MSXML была отправлена ​​с Internet Explorer 5.0 в марте 1999 г., обеспечивая доступ через ActiveX к интерфейсу IXMLHTTPRequest с помощью XMLHTTP оболочка библиотеки MSXML

Internet Explorer версий 5 и 6 не определял идентификатор объекта XMLHttpRequest на своих языках сценариев, поскольку сам идентификатор XMLHttpRequest не был стандартом на момент их выпуска. совместимость может быть достигнута путем обнаружения объекта, если идентификатор XMLHttpRequest не существует. Microsoft добавила идентификатор объекта XMLHttpRequest к своим языкам сценариев в Internet Explorer 7.0, выпущенном в октябре 2006 года.

В рамках проекта Mozilla был разработан и реализован интерфейс под названием nsIXMLHttpRequest в механизме компоновки Gecko. Этот интерфейс был разработан таким образом, чтобы максимально приближать его к интерфейсу Microsoft IXMLHTTPRequest. Mozilla создала оболочку для использования этого интерфейса через объект JavaScript, который они назвали XMLHttpRequest. Объект XMLHttpRequest был доступен еще в Gecko версии 0.6, выпущенной 6 декабря 2000 г., но он не был полностью функциональным до версии 1.0 Gecko, выпущенной 5 июня 2002 г. Объект XMLHttpRequest стал де-факто стандартом в других основных веб-клиентах, реализованных в Safari 1.2, выпущенном в феврале 2004 г., Konqueror, Opera 8.0, выпущенном в апреле 2005 г., и iCab 3.0b352, выпущенном в сентябре 2005 г. .

С появлением кроссбраузерных библиотек JavaScript, таких как jQuery, разработчики могут вызывать функциональность XMLHttpRequest без программирования непосредственно в API.

подробнее см. в Википедии.

Приступим к написанию кода 😊

Это очень простой исходный код

const request = new XMLHttpRequest();
const url = 'https://jsonplaceholder.typicode.com/todos/1';
request.open("GET", url);
request.send();

Чтобы отправить HTTP-запрос:

  • создать объект XMLHttpRequest,
  • открыть URL-адрес,
  • отправить заявку.

После завершения транзакции объект будет содержать полезную информацию, такую ​​как тело ответа и HTTP-статус результата.

Но нам нужно что-то сделать с данными (ответом) или отловить ошибки, поэтому мы будем использовать addEventListener ().

addEventListener () - это встроенная функция в JavaScript, которая принимает событие для прослушивания и второй аргумент, вызываемый при каждом запуске описанного события. К одному элементу можно добавить любое количество обработчиков событий без перезаписи существующих обработчиков событий.

поэтому мы будем использовать событие загрузки, оно будет запущено после получения ответа от сервера.

Давайте посмотрим на этот пример:

const request = new XMLHttpRequest();
const url = 'https://jsonplaceholder.typicode.com/todos/1';
request.open("GET", url);
request.send();
request.addEventListener('load', (e) => {
    if (request.status === 200) {
        const response= JSON.parse(request.response);
        console.log(response);
        /*
          console will print the response 
        {
            "userId": 1,
            "id": 1,
            "title": "delectus aut autem",
            "completed": false
        }
         */
    }
});

есть и другие события, которые вы можете использовать, например: load, startprogress, abort, error, load, timeout, loadend, readystatechange,

в последнем коде. Мы ввели свойство status объекта XMLHttpRequest, вы должны знать, что есть еще что-то, называемое readyState, хранящее число от 0 до 4, показывающее ход выполнения запроса.

0 - означает, что запрос не был инициализирован.

1 - означает, что соединение с сервером установлено.

2 - означает, что запрос отправлен.

3 - означает, что запрос обработан.

4 - запрос был успешным и ответ, если готов.

Итак, мы обновим функцию responseHandler:

function responseHandler() {
 if (request.readyState === 4 && request.status === 200) {
 const response = JSON.parse(request.response);
 console.log(response);
 }
}

Я уверен, что вы сейчас думаете о заголовках 😊

вы можете использовать setRequestHeader (header, value), чтобы установить заголовки для запроса:

request.setRequestHeader('Accept-Language', 'en-US');

обязательно поместите эту строку после request.open (), если нет, вы получите эту ошибку в консоли:

Обработка событий и ошибок.

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

request.addEventListener('error', errorHandler);
function errorHandler(){
    console.log('sorry something went wrong’);
}

errorHandler () срабатывает при возникновении ошибки.

request.addEventListener('abort', abortHandler);
function abortHandler(){
    console.log('sorry the request was aborted');
}

abortHandler () срабатывает, когда запрос прерывается.

давайте обработаем событие прогресса:

request.addEventListener('progress', updateProgress);
function updateProgress(event) {
    if (event.lengthComputable) {
        let percent = (event.loaded / event.total) * 100;
        console.log(percent)
    } else {
        // Unable to compute progress information since the total size is unknown
    }
}

updateProgress () запускается при изменении состояния готовности.

Обработчик события progress, указанный функцией updateProgress() в этом примере, получает общее количество байтов для передачи, а также количество байтов, переданных на данный момент, в полях события total и loaded. Однако, если поле lengthComputable имеет значение false, общая длина неизвестна и будет равна нулю.

  • event.loaded объем передаваемых в настоящее время данных.
  • event.total общий объем передаваемых данных.

Пример.

(1/4) * 100 = 25%

Это хорошо для пользователей, поэтому обязательно используйте анимацию = 😁

Посмотрим весь код

const request = new XMLHttpRequest();
const url = 'https://jsonplaceholder.typicode.com/todos/1';
request.addEventListener('load', responseHandler);//fires when the readyState changes.
request.addEventListener("progress", updateProgress);// fires when the request is aborted.
request.addEventListener('abort', abortHandler);// fires when an error occurs
request.addEventListener('error', errorsHandler);// fires only when the request is successfull.
function responseHandler() {
   if (request.readyState === 4 && request.status === 200) {
         const response = JSON.parse(request.response);
         console.log(response);
       } else {
           console.log('something went wrong', request.status) // will print 404 as a example
}
}
function updateProgress(event) {
if (event.lengthComputable) {
let percent = (event.loaded / event.total) * 100;
console.log(percent)
} else {
// Unable to compute progress information since the total size is unknown
}
}
function abortHandler(event) {
console.log('sorry the request was aborted', event);
}
function errorsHandler(event) {
 console.log(‘sorry something went wrong’, event.status);
}
 
 request.open(“GET”, url);
 request.setRequestHeader(‘Accept-Language’, ‘en-US’);
 request.send();

Типы запросов

Запрос, сделанный через XMLHttpRequest, может получать данные одним из двух способов: асинхронно или синхронно. Тип запроса определяется необязательным аргументом async (третий аргумент), который устанавливается в методе XMLHttpRequest.open (). Если этот аргумент истинен или не указан, XMLHttpRequest обрабатывается асинхронно, в противном случае процесс обрабатывается синхронно.

request.open(“GET”, url, true);

асинхронным запросам следует отдавать предпочтение по соображениям производительности, чем синхронным запросам, поскольку синхронные запросы блокируют выполнение кода, что приводит к «зависанию» экрана и отсутствию ответа у пользователя.

дальнейшее чтение

На этом пока все. Этот пост направлен на то, чтобы дать новичкам объяснение объекта XMLHttpRequest изнутри.