Отправка запросов

Отправка HTTP-запросов — ключевая задача при взаимодействии с API. В JavaScript и TypeScript для этого чаще всего используется встроенная функция fetch. Она доступна как в браузере, так и в современных версиях Node.js (начиная с v18). Существуют и другие инструменты, например, библиотека Axios, которая предлагает более удобный API, автоматическое преобразование данных и лучшую поддержку отмены запросов. Однако в рамках этого курса мы используем только fetch, чтобы изучить базовые принципы работы с сетью без зависимости от сторонних библиотек.

Основы использования fetch

Функция fetch принимает два аргумента:

  • URL эндпоинта (обязательно)
  • Объект с настройками запроса (опционально)

Она возвращает промис, который разрешается в объект Response.

Простой GET-запрос:

const response = await fetch('https://api.example.com/users');

Опции запроса

Второй аргумент — объект с параметрами:

const response = await fetch('/api/profile', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer token123'
  },
  body: JSON.stringify({ name: 'Alex' })
});

Основные опции:

  • method — HTTP-метод: 'GET', 'POST', 'PUT', 'DELETE' и др.
  • headers — заголовки запроса. Можно передать как обычный объект или экземпляр класса Headers.

Пример с объектом (чаще используется):

headers: {
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

Пример с классом Headers (полезно при динамическом добавлении):

const headers = new Headers();
headers.append('Content-Type', 'application/json');
headers.append('Authorization', 'Bearer xyz');

// затем в fetch:
fetch(url, { headers });

Оба подхода эквивалентны. Использование объекта проще и читаемее, поэтому он предпочтителен в большинстве случаев.

  • body — тело запроса. Допустимые типы: строка, FormData, URLSearchParams, Blob, ArrayBuffer.

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

Объект Response содержит метаданные и методы для чтения тела ответа:

  • response.ok — true, если статус ответа в диапазоне 200–299.
  • response.status — числовой код статуса (например, 200, 404, 500).
  • response.json() — парсит тело ответа как JSON и возвращает промис с результатом.
  • response.text() — возвращает тело как строку.
  • response.blob() — возвращает тело как бинарный объект (полезно для изображений, файлов).

Пример обработки:

const response = await fetch('/api/user/1');

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

const user = await response.json();
console.log(user.name);

Отправка полезной нагрузки

Отправка JSON

Для отправки структурированных данных используется JSON:

const userData = { name: 'Alex', email: 'alex@example.com' };

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

Заголовок Content-Type: application/json обязателен, чтобы сервер корректно интерпретировал тело запроса.

Отправка FormData

При работе с файлами или формами используется FormData:

const formData = new FormData();
formData.append('email', 'alex@example.com');
formData.append('avatar', fileInput.files[0]); // File из <input type="file">

const response = await fetch('/api/upload', {
  method: 'POST',
  body: formData
  // Content-Type НЕ указывается — браузер установит его автоматически
});

Если вы укажете Content-Type вручную при использовании FormData, запрос может сломаться, так как браузер не сможет добавить необходимый boundary.

Отправка URL-encoded данных

Иногда API требует данные в формате HTML-форм:

const data = { username: 'alex', password: 'secret' };
const params = new URLSearchParams(data);

const response = await fetch('/login', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/x-www-form-urlencoded'
  },
  body: params.toString()
});

Этот подход встречается реже, но полезен при интеграции с legacy-системами или простыми серверами.