Fetch API у JavaScript надає зручний спосіб виконувати HTTP-запити та отримувати дані з віддалених серверів. Він вбудований у сучасні браузери та доступний у Node.js (починаючи з версії 18), працює асинхронно та дозволяє легко взаємодіяти з API без використання сторонніх бібліотек.

У цьому дописі ми розглянемо ключові можливості Fetch API та практичні приклади їх застосування.

Зміст:

  1. Базовий приклад запиту Fetch
  2. Відправка даних за допомогою POST-запиту
  3. Обробка кодів стану відповіді
  4. Синтаксис async/await
  5. Відправка запитів з параметрами
  6. Обробка помилок і тайм-аутів

Базовий приклад запиту Fetch

Найпростіше застосування Fetch API – це отримання даних з сервера. Виклик функції fetch() повертає Promise, який після виконання містить об’єкт Response. Саме він представляє відповідь сервера на запит і дозволяє далі працювати з отриманими даними.

Приклад:

// Виконуємо GET-запит для отримання списку користувачів з API
fetch('https://jsonplaceholder.typicode.com/users')
  .then((response) => {
    // Перевіряємо, чи відповідь успішна (статус 200–299)
    if (!response.ok) {
      throw new Error('Помилка мережі: статус відповіді не OK');
    }
    return response.json(); // Отримуємо дані з відповіді як JSON-об’єкт
  })
  .then((users) => {
    // Обробляємо отримані дані (наприклад, виводимо список користувачів у консоль)
    users.forEach((user) => {
      console.log(`${user.name}${user.email}`);
    });
  })
  // Обробка помилок
  .catch((error) => {
    console.error('Помилка під час виконання fetch-запиту:', error);
  });

/*Output:
Leanne Graham — Sincere@april.biz
Ervin Howell — Shanna@melissa.tv
Clementine Bauch — Nathan@yesenia.net
.....
*/

Пояснення:

  • fetch('https://...') – виконує GET-запит до API-ендпоінту.
  • then(response => ...) – перевіряє, чи відповідь була успішною. Якщо статус не в діапазоні 200299, генерується помилка.
  • response.json() – отримує тіло відповіді як JSON-об’єкт, зручний для подальшої роботи.
  • then(users => ...) – отримує дані та обробляє їх (у прикладі ми виводимо name та email користувачів у консоль).
  • catch(error => …) – перехоплює та обробляє помилки, що можуть виникнути під час запиту або обробки даних.

Відправка даних за допомогою POST-запиту

Функцію fetch() можна використовувати не лише для отримання інформації, а й для відправки даних на сервер. Для цього потрібно:

  • вказати параметр method: 'POST'
  • передати потрібні заголовки (наприклад, Content-Type: application/json)
  • додати тіло запиту через body, попередньо перетворивши об’єкт у JSON за допомогою JSON.stringify()

У прикладі нижче ми створюємо нового користувача, відправивши його name та email у форматі JSON:

fetch('https://jsonplaceholder.typicode.com/users', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    name: 'John Doe',
    email: 'john@example.com',
  }),
})
  .then((response) => {
    if (!response.ok) {
      throw new Error('Помилка мережі: статус відповіді не OK');
    }
    return response.json();
  })
  .then((user) => {
    console.log('Новий користувач створений:', user);
  })
  .catch((error) => {
    console.error('Помилка під час виконання fetch-запиту:', error);
  });

/*Output:
Новий користувач створений: { name: 'John Doe', email: 'john@example.com', id: 11 }
*/

Обробка кодів стану відповіді

API може повертати різні HTTP-коди статусу, і корисно передбачати власну логіку обробки для кожного випадку. Це дає змогу не лише виявляти помилки, а й показувати користувачу зрозумілі повідомлення.

Наприклад:

  • 200 OK – запит виконано успішно
  • 404 Not Found – ресурс не знайдено
  • 500 Internal Server Error – проблема на стороні сервера

Приклад:

fetch('https://jsonplaceholder.typicode.com/users/999') // неіснуючий користувач
  .then((response) => {
    switch (response.status) {
      case 200:
        return response.json();
      case 404:
        throw new Error('Ресурс не знайдено (404)');
      case 500:
        throw new Error('Внутрішня помилка сервера (500)');
      default:
        throw new Error(`Неочікуваний статус відповіді: ${response.status}`);
    }
  })
  .then((data) => {
    console.log('Отримані дані:', data);
  })
  .catch((error) => {
    console.error('Помилка під час виконання fetch-запиту:', error.message);
  });

/*Output:
Помилка під час виконання fetch-запиту: Ресурс не знайдено (404)
*/

Синтаксис async/await

Для кращої читабельності та зручності роботи з асинхронним кодом, можна використовувати async/await замість ланцюжків .then(). Такий підхід робить код більш схожим на звичайний синхронний, що спрощує його розуміння та підтримку.

Приклад:

// Отримуємо список користувачів за допомогою async/await
async function fetchUsers() {
  try {
    const response = await fetch('https://jsonplaceholder.typicode.com/users');

    if (!response.ok) {
      throw new Error(`Помилка: статус ${response.status}`);
    }

    const users = await response.json();
    console.log('Отримані користувачі:', users);
  } catch (error) {
    console.error('Помилка під час виконання fetch-запиту:', error.message);
  }
}

fetchUsers();

/*Output:
Отримані користувачі: [
  {
    id: 1,
    name: 'Leanne Graham',
    username: 'Bret',
    email: 'Sincere@april.biz',
    address: {
      street: 'Kulas Light',
      suite: 'Apt. 556',
      city: 'Gwenborough',
      zipcode: '92998-3874',
      geo: [Object]
    },
    ......
*/

У цьому прикладі:

  • ключове слово async визначає асинхронну функцію, яка повертає Promise
  • await «чекає», поки Promise буде виконано, і повертає його результат
  • усі помилки обробляються в блоці try...catch, що робить код більш чистим і зрозумілим

Відправка запитів з параметрами

Іноді виникає потреба передати на сервер додаткові дані у вигляді query parameters – наприклад, для фільтрації, сортування чи пагінації. У такому випадку параметри додаються до URL у форматі:

?ключ=значення

Приклад:

// Отримуємо пости з параметрами запиту
// Наприклад: лише перші 5 постів користувача з id=1
fetch('https://jsonplaceholder.typicode.com/posts?userId=1&_limit=5')
  .then((response) => {
    if (!response.ok) {
      throw new Error(`Помилка: статус ${response.status}`);
    }
    return response.json();
  })
  .then((posts) => {
    console.log('Отримані пости:', posts);
  })
  .catch((error) => {
    console.error('Помилка під час виконання fetch-запиту:', error.message);
  });

/*Output:
Отримані пости: [
  {
    userId: 1,
    id: 1,
    title: 'sunt aut facere repellat provident occaecati excepturi optio reprehenderit',
    body: 'quia et suscipit\n' +
      'suscipit recusandae consequuntur expedita et cum\n' +
      'reprehenderit molestiae ut ut quas totam\n' +
      'nostrum rerum est autem sunt rem eveniet architecto'
  },
  .....
*/

У цьому прикладі:

  • userId=1 – отримуємо пости конкретного користувача
  • _limit=5 – обмежуємо кількість результатів до 5
  • параметри можна комбінувати, додаючи їх через символ &

Обробка помилок і тайм-аутів

Іноді запити API можуть завершуватися невдало через проблеми з мережею або сервером. Також бувають ситуації, коли відповідь занадто довго не надходить. У таких випадках варто передбачати логіку обробки помилок і тайм-аутів, щоб користувач отримував зрозуміле повідомлення.

Приклад:

// Виконуємо fetch із тайм-аутом у 5 секунд
async function fetchWithTimeout(url, timeout = 5000) {
  const controller = new AbortController();
  const timer = setTimeout(() => controller.abort(), timeout);

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

    if (!response.ok) {
      throw new Error(`Помилка: статус ${response.status}`);
    }

    return await response.json();
  } catch (error) {
    if (error.name === 'AbortError') {
      console.error('Запит було скасовано через тайм-аут');
    } else {
      console.error('Помилка під час виконання fetch-запиту:', error.message);
    }
  } finally {
    clearTimeout(timer);
  }
}

// Використання
fetchWithTimeout('https://jsonplaceholder.typicode.com/users').then((users) => {
  if (users) {
    console.log('Отримані користувачі:', users);
  }
});

/*Output:
Отримані користувачі: [
  {
    id: 1,
    name: 'Leanne Graham',
    username: 'Bret',
    email: 'Sincere@april.biz',
    address: {
      street: 'Kulas Light',
      suite: 'Apt. 556',
      city: 'Gwenborough',
      zipcode: '92998-3874',
      geo: [Object]
    },
  .....
*/

У цьому прикладі:

  • AbortController використовується для створення сигналу скасування запиту
  • через setTimeout() викликається controller.abort(), якщо час очікування перевищує 5 секунд
  • якщо сервер повернув помилку (наприклад 500), ми виводимо повідомлення з отриманим кодом статусу
  • якщо запит перервано через тайм-аут, помилка матиме тип AbortError і буде оброблена окремо

Підсумок

Fetch API – це зручний інструмент для роботи з HTTP-запитами у JavaScript. За допомогою функції fetch() можна легко:

  • отримувати дані з сервера та відправляти їх на сервер
  • працювати з параметрами запитів
  • обробляти коди статусу відповіді
  • використовувати зручний синтаксис async/await
  • передбачати сценарії з помилками та тайм-аутами

Це робить Fetch API універсальним вибором для більшості завдань, пов’язаних із взаємодією між клієнтом і сервером.

Більше інформації в офіційній документації: Fetch API


Мітки: