HTTP клиент на JavaScript: делаем запросы правильно в Node.js

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

HTTP клиент на JavaScript: делаем запросы правильно в Node.js

Современная веб-разработка немыслима без взаимодействия с удалёнными серверами. Будь то получение данных с REST API, отправка форм или загрузка файлов — HTTP-запросы лежат в основе любой интеграции. Если вы разрабатываете на Node.js, то у вас есть несколько мощных инструментов для создания HTTP-клиента. В этой статье мы разберём, как делать запросы правильно: от встроенных модулей до популярных библиотек, с акцентом на обработку ошибок, таймауты и читаемость кода.

Мы рассмотрим три основных подхода: встроенный модуль http/https, современный fetch (доступный в Node.js 18+) и легендарную библиотеку axios. Для каждого подхода вы найдёте практические примеры и рекомендации.

1. Встроенный модуль http/https: классика жанра

Node.js с самого начала включает модули http и https для работы с сетевыми запросами. Это самый низкоуровневый способ, который даёт полный контроль над процессом. Однако он требует больше кода для обработки ответа.

Пример GET-запроса с использованием модуля https:

const https = require('https');

function getUsers() {
  return new Promise((resolve, reject) => {
    const options = {
      hostname: 'jsonplaceholder.typicode.com',
      path: '/users',
      method: 'GET',
      headers: {
        'Content-Type': 'application/json'
      }
    };

    const req = https.request(options, (res) => {
      let data = '';

      // Собираем данные по частям
      res.on('data', (chunk) => {
        data += chunk;
      });

      // Когда ответ полностью получен
      res.on('end', () => {
        if (res.statusCode >= 200 && res.statusCode < 300) {
          resolve(JSON.parse(data));
        } else {
          reject(new Error(`HTTP Error: ${res.statusCode}`));
        }
      });
    });

    // Обработка ошибок сети
    req.on('error', (err) => {
      reject(err);
    });

    // Таймаут на случай зависания
    req.setTimeout(5000, () => {
      req.destroy();
      reject(new Error('Request timeout'));
    });

    req.end();
  });
}

// Использование
getUsers()
  .then(users => console.log('Users:', users.length))
  .catch(err => console.error('Error:', err.message));

Плюсы:

  • Не требует установки дополнительных пакетов.
  • Полный контроль над каждым этапом соединения.

Минусы:

  • Много шаблонного кода.
  • Ручная обработка чанков и сборка тела ответа.
  • Неудобная работа с промисами без обёртки.

Этот подход оправдан, если вы пишете библиотеку для работы с сетью или вам нужна максимальная производительность без лишних зависимостей. В остальных случаях лучше использовать более высокоуровневые решения.

2. Fetch API: современный стандарт

Начиная с Node.js 18, fetch стал встроенной функцией, что сделало его основным инструментом для HTTP-запросов. Он основан на промисах и имеет чистый, интуитивно понятный синтаксис.

Пример POST-запроса с fetch:

async function createPost() {
  const url = 'https://jsonplaceholder.typicode.com/posts';
  const newPost = {
    title: 'HTTP клиент на JavaScript',
    body: 'Делаем запросы правильно',
    userId: 1
  };

  try {
    const response = await fetch(url, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(newPost)
    });

    // Проверяем статус ответа
    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }

    const data = await response.json();
    console.log('Created post ID:', data.id);
    return data;
  } catch (error) {
    console.error('Fetch error:', error.message);
    throw error;
  }
}

createPost();

Пример с таймаутом и обработкой ошибок:

async function fetchWithTimeout(url, options = {}, timeout = 5000) {
  const controller = new AbortController();
  const timeoutId = setTimeout(() => controller.abort(), timeout);

  try {
    const response = await fetch(url, {
      ...options,
      signal: controller.signal
    });

    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }

    return await response.json();
  } catch (error) {
    if (error.name === 'AbortError') {
      throw new Error('Request was aborted (timeout)');
    }
    throw error;
  } finally {
    clearTimeout(timeoutId);
  }
}

// Использование
fetchWithTimeout('https://api.example.com/data', {}, 3000)
  .then(data => console.log(data))
  .catch(err => console.error('Error:', err.message));

Плюсы:

  • Встроен в Node.js (18+), не требует установки.
  • Промис-ориентированный, лаконичный синтаксис.
  • Поддержка AbortController для отмены запросов.

Минусы:

  • Нет автоматической обработки ошибок (HTTP статусы 4xx/5xx не вызывают reject).
  • Нет встроенной поддержки прогресса загрузки.
  • В старых версиях Node.js (до 18) требуется полифилл.

3. Axios: мощный и удобный инструмент

Библиотека axios остаётся одним из самых популярных HTTP-клиентов для Node.js. Она предоставляет удобный API, автоматическую трансформацию JSON, интерцепторы и множество других полезных функций.

Установка:

npm install axios

Базовый GET-запрос с обработкой ошибок:

const axios = require('axios');

async function fetchUserData(userId) {
  try {
    const response = await axios.get(`https://jsonplaceholder.typicode.com/users/${userId}`);
    console.log('User:', response.data.name);
    return response.data;
  } catch (error) {
    if (error.response) {
      // Сервер ответил с кодом ошибки
      console.error('Server error:', error.response.status, error.response.data);
    } else if (error.request) {
      // Запрос был отправлен, но ответа нет
      console.error('No response received:', error.message);
    } else {
      // Ошибка при настройке запроса
      console.error('Request setup error:', error.message);
    }
    throw error;
  }
}

fetchUser                

Блоги

Рекомендаций по книгам