Что такое XHR (XMLHttpRequest) в веб-разработке?

Ответ

XHR (XMLHttpRequest) — это API, предоставляемый браузерами, который позволяет клиентскому JavaScript-коду отправлять HTTP- или HTTPS-запросы к веб-серверу и асинхронно обрабатывать ответы без необходимости перезагрузки страницы. Это фундаментальная технология для AJAX (Asynchronous JavaScript and XML).

Ключевые возможности:

  • Асинхронные запросы: Основной режим работы, не блокирующий интерфейс пользователя.
  • Поддержка различных протоколов: HTTP, HTTPS, FTP, file.
  • Разные HTTP-методы: GET, POST, PUT, DELETE, HEAD, OPTIONS.
  • Работа с различными форматами данных: XML (исторически), JSON, HTML, plain text.
  • Отслеживание прогресса: События progress, load, error для мониторинга загрузки/выгрузки (полезно для файлов).

Базовый пример использования XHR для GET-запроса:

// 1. Создание объекта XHR
const xhr = new XMLHttpRequest();

// 2. Настройка запроса: метод GET, URL, асинхронный режим (true)
xhr.open('GET', 'https://api.example.com/users', true);

// 3. Установка обработчиков событий
xhr.onload = function() {
  // Проверка успешного статуса ответа (2xx)
  if (xhr.status >= 200 && xhr.status < 300) {
    // Парсинг JSON-ответа
    const users = JSON.parse(xhr.responseText);
    console.log('Данные получены:', users);
  } else {
    console.error('Ошибка запроса. Статус:', xhr.status);
  }
};

xhr.onerror = function() {
  console.error('Произошла ошибка сети');
};

// 4. Отправка запроса (для GET тело не требуется)
xhr.send();

Пример POST-запроса с отправкой JSON:

const xhr = new XMLHttpRequest();
xhr.open('POST', 'https://api.example.com/login', true);

// Указание типа контента в заголовке
xhr.setRequestHeader('Content-Type', 'application/json');

xhr.onload = function() {
  if (xhr.status === 200) {
    console.log('Успешный вход:', xhr.responseText);
  }
};

const data = JSON.stringify({ username: 'john', password: 'secret' });
xhr.send(data); // Отправка строки JSON

Современная альтернатива — Fetch API: XHR считается устаревшим (legacy) API. Современная замена — более мощный и удобный Fetch API, основанный на Promise.

Сравнение XHR и Fetch:

// Один и тот же GET-запрос, реализованный двумя способами:

// 1. С помощью XHR (старый способ)
const xhr = new XMLHttpRequest();
xhr.open('GET', '/api/data');
xhr.onload = () => console.log(xhr.response);
xhr.send();

// 2. С помощью Fetch API (современный способ)
fetch('/api/data')
  .then(response => response.json())
  .then(data => console.log(data))
  .catch(error => console.error('Error:', error));

Значение для тестирования: Понимание XHR важно для:

  1. Тестирования API: Анализ сетевых запросов в DevTools (вкладка Network).
  2. Отладки: Проверка корректности отправляемых данных и получаемых ответов.
  3. Написания E2E-тестов: Инструменты вроде Selenium могут перехватывать и валидировать XHR-запросы.

Ответ 18+ 🔞

А, слушай, вот эта штука — XHR. Ну, XMLHttpRequest, если по-паспорту. Представь себе, браузерный такой старичок, который умеет тихонько, без всей этой дурацкой перезагрузки страницы, сходить на сервер, что-то спросить и притащить ответ обратно. Вся магия этих динамических штук, когда контент подгружается, — это его, сука, рук дело. Основа AJAX, короче.

Что он умеет, этот дед:

  • Шпионить асинхронно: Основная фишка. Он не будет тормозить весь интерфейс, пока ждёт ответа. Отправил запрос и пошёл дальше по своим делам, ответ придёт — позовёт.
  • По всем протоколам шастать: HTTP, HTTPS, даже до FTP и file:// докопается.
  • Все методы HTTP юзать: GET, POST, PUT — что душе угодно.
  • Любые данные таскать: Раньше для XML придумали, но он и JSON, и HTML, и простой текст схавает.
  • Отчитываться о прогрессе: Можно подписаться на события, чтобы видеть, насколько уже загрузился большой файл. Удобно, если не хочешь, чтобы пользователь думал, что всё накрылось.

Вот, смотри, как им попользоваться, чтобы GET-запрос сделать:

// 1. Рождаем объект, ёпта
const xhr = new XMLHttpRequest();

// 2. Настраиваем: куда идём, как идём (GET), идём тихо (true — асинхронно)
xhr.open('GET', 'https://api.example.com/users', true);

// 3. Вешаем слушателей, чтобы знать, что происходит
xhr.onload = function() {
  // Если сервер ответил "всё ок" (статус 2xx)
  if (xhr.status >= 200 && xhr.status < 300) {
    // Распарсим JSON, который нам прислали
    const users = JSON.parse(xhr.responseText);
    console.log('Данные получены, можно расслабиться:', users);
  } else {
    console.error('Ошибка, блядь! Сервер сказал:', xhr.status);
  }
};

xhr.onerror = function() {
  console.error('Вообще хуйня, сеть сдохла');
};

// 4. Отправляемся в путь. Для GET тела не надо.
xhr.send();

А вот если нужно что-то отправить, типа POST с JSON:

const xhr = new XMLHttpRequest();
xhr.open('POST', 'https://api.example.com/login', true);

// Говорим серверу: "Держи, братан, это JSON, не пугайся"
xhr.setRequestHeader('Content-Type', 'application/json');

xhr.onload = function() {
  if (xhr.status === 200) {
    console.log('Ура, залогинились:', xhr.responseText);
  }
};

// Пакуем данные в строку и отправляем
const data = JSON.stringify({ username: 'vasya', password: 'qwerty123' });
xhr.send(data);

Но есть нюанс, ёпта! Этот XHR — он уже как дедушка, который вспоминает молодость. Есть более крутой и модный пацан — Fetch API. Он на промисах, с ним код чище и приятнее.

Сравни, как одна и та же задача решается по-старому и по-новому:

// 1. Старая школа — XHR (ностальгия, блядь)
const xhr = new XMLHttpRequest();
xhr.open('GET', '/api/data');
xhr.onload = () => console.log(xhr.response);
xhr.send();

// 2. Новая школа — Fetch (красиво и с промисами)
fetch('/api/data')
  .then(response => response.json())
  .then(data => console.log(data))
  .catch(error => console.error('Всё пропало, шеф:', error));

Зачем это всё тестировщику или разработчику?

  1. Чтобы API тестить: Открываешь в DevTools вкладку Network и смотришь, какие запросы улетают, что в них, что приходит. Без этого — как без рук.
  2. Чтобы дебажить: Если что-то не работает, первым делом смотришь — а тот ли запрос ушёл? А тот ли ответ пришёл?
  3. Для E2E-тестов: Умные фреймворки могут ловить эти XHR-запросы и проверять, всё ли с ними в порядке. Полезная, блядь, штука.