JavaScript: Fetch vs XMLHttpRequest — асинхронные запросы

Рассмотрим взаимодействие с сервером при помощи асинхронных запросов на чистом JavaScript, без сторонних библиотек. Используем два способа: XMLHttpRequest (XHR) и Fetch API.

Использование сервиса JSON Placeholder

Для отправки запросов используем сервис JSON Placeholder — фейковый онлайн REST API для тестирования и прототипирования. Он предоставляет различные примеры ресурсов, включая ресурс users, возвращающий JSON-массив пользователей. Его URL используется в запросах.

XMLHttpRequest (XHR)

XHR — аббревиатура от XMLHTTPRequest. Создадим объект при помощи конструктора глобального класса XMLHttpRequest:

let xhr = new XMLHttpRequest();

Отправим запрос методом open(). Первый параметр — метод запроса (GET, POST, PUT, PATCH, DELETE), второй — URL. Используем GET-запрос для получения данных с /users:

xhr.open('GET', 'https://jsonplaceholder.typicode.com/users');

После open() отправим запрос методом send():

xhr.send();

Для проверки запроса воспользуйтесь вкладкой Network в DevTools браузера. Она отображает все сетевые запросы, включая XHR-запросы, с возможностью фильтрации по типу, методу и другим параметрам. Вкладка содержит информацию о заголовках запроса (Request Headers), ответе сервера (Response Headers), самом ответе (Response) и других данных.

Обработка ответа и ошибок

Ответ сервера — строка. Для работы с ней как с JavaScript-объектом используем JSON.parse(). Обработка ответа и ошибок осуществляется обработчиками событий onload и onerror:

xhr.onload = function() {
  if (xhr.status >= 200 && xhr.status < 400) {
    console.log('Успешный ответ:', JSON.parse(xhr.responseText));
  } else {
    console.error('Ошибка:', xhr.status);
  }
};

xhr.onerror = function() {
  console.error('Ошибка запроса');
};

xhr.responseText содержит строку, JSON.parse() преобразует её в объект. onload проверяет статус ответа (200-399 — успешный ответ). onerror вызывается при ошибке запроса (например, отсутствии соединения). Для более детальной обработки ошибок можно использовать xhr.status и xhr.statusText.

Метод POST

Для отправки POST-запросов добавим тело запроса (body) и укажем заголовок Content-Type:

let data = { name: 'Vladilen', age: 26 };
xhr.open('POST', 'https://jsonplaceholder.typicode.com/users');
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.send(JSON.stringify(data));

Обратите внимание на JSON.stringify() для преобразования объекта data в JSON-строку.

Универсальная функция с Promise

Для улучшения читаемости и удобства работы с асинхронным кодом создадим универсальную функцию sendRequest(), использующую Promise:

function sendRequest(method, url, body = null) {
  return new Promise((resolve, reject) => {
    const xhr = new XMLHttpRequest();
    xhr.open(method, url);
    xhr.responseType = 'json'; // Ожидаем JSON-ответ

    xhr.onload = () => {
      if (xhr.status >= 200 && xhr.status < 400) {
        resolve(xhr.response);
      } else {
        reject(xhr.status);
      }
    };

    xhr.onerror = () => {
      reject(new Error('Ошибка запроса'));
    };

    xhr.setRequestHeader('Content-Type', 'application/json'); // Заголовок для POST-запросов
    xhr.send(body); // Отправляем тело запроса, если оно есть
  });
}

Функция принимает метод, URL и необязательное тело запроса. Она возвращает Promise, разрешающийся успешным ответом или отклоняющийся ошибкой.

Fetch API

Fetch API — более современный способ работы с асинхронными запросами, также возвращающий Promise:

function sendRequest(method, url, body = null) {
  const headers = { 'Content-Type': 'application/json' }; // Заголовки

  return fetch(url, {
    method,
    headers,
    body: body ? JSON.stringify(body) : null // Тело запроса
  }).then(response => {
    if (!response.ok) {
      throw new Error(`Ошибка HTTP: ${response.status}`); // Выбрасываем ошибку при неуспешном ответе
    }
    return response.json(); // Возвращаем Promise с парсингом JSON-ответа
  });
}

Функция аналогична предыдущей, но использует fetch. Обратите внимание на обработку ошибок с помощью response.ok и выброс исключения.

Рассмотрены два способа отправки асинхронных запросов на сервер: XMLHttpRequest и Fetch API. Fetch API более современный и удобный, но XHR остаётся универсальным и поддерживается всеми браузерами. Выбор метода зависит от требований проекта и предпочтений разработчика. Важно понимать принципы клиент-серверного взаимодействия и уметь обрабатывать ответы и ошибки.

Что будем искать? Например,программа