Axios – це популярна JavaScript-бібліотека для роботи з HTTP-запитами. Вона спрощує надсилання асинхронних запитів до REST-ендпоінтів, обробку відповідей та роботу з помилками. Axios однаково добре підходить як для браузера, так і для Node.js, надаючи уніфікований та передбачуваний інтерфейс для взаємодії з будь-яким API.

Зміст допису:

  1. Основні можливості Axios
  2. Встановлення Axios
  3. Базові приклади
  4. Використання async/await
  5. Обробка помилок
  6. Налаштування заголовків
  7. Створення власного Axios-клієнта
  8. Перехоплювачі (Interceptors)
  9. Скасування запитів

Основні можливості Axios

  • Побудований на Promise: підтримує .then(), .catch() та сучасний синтаксис async/await, завдяки чому робота з асинхронним кодом є передбачуваною та зручною.
  • Підтримка всіх HTTP-методів: GET, POST, PUT, PATCH, DELETE та інші.
  • Автоматична обробка JSON: Axios самостійно перетворює дані у форматі JSON – без необхідності викликати JSON.parse() чи JSON.stringify().
  • Підтримка браузера та Node.js: інтерфейс єдиний, незалежно від середовища виконання.
  • Гнучкі налаштування за замовчуванням: можливість створювати екземпляри клієнта з власними baseURL, заголовками, тайм-аутами та іншими параметрами.
  • Перехоплювачі (interceptors): дозволяють модифікувати запити до виконання або відповіді перед їх обробкою.
  • Скасування запитів: можливість відмінити запит, якщо він стає непотрібним (наприклад, при зміні сторінки або дублюванні запитів).

Встановлення Axios

Найпростіший спосіб додати Axios у проєкт – встановити його через npm або yarn:

npm install axios

або:

yarn add axios

Якщо ви працюєте з браузерним проєктом без збирача (npm, bundler), можна підключити Axios напряму через CDN:

<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>

Базові приклади

Axios дозволяє легко виконувати HTTP-запити та обробляти відповіді. Він підтримує параметри запиту, користувацькі заголовки та роботу з різними HTTP-методами.

Приклад GET-запиту:

import axios from 'axios';

axios
  .get('https://jsonplaceholder.typicode.com/posts/1')
  .then((response) => {
    console.log('Data:', response.data);
    console.log('Status:', response.status);
    console.log('Headers:', response.headers);
  })
  .catch((error) => {
    console.error(error);
  });

Приклад POST-запиту:

import axios from 'axios';

axios
  .post('https://jsonplaceholder.typicode.com/posts', {
    title: 'New post',
    body: 'Post content',
    userId: 1,
  })
  .then((response) => {
    console.log(response.data);
  })
  .catch((error) => {
    console.error(error);
  });

Використання async/await

Axios підтримує синтаксис async/await, що дозволяє писати асинхронні запити у стилі звичайного синхронного коду:

import axios from 'axios';

async function fetchPost() {
  try {
    const response = await axios.get('https://jsonplaceholder.typicode.com/posts/1');
    console.log('Data:', response.data);
  } catch (error) {
    console.error('Error fetching post:', error);
  }
}

fetchPost();

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

  • axios.get() повертає Promise, який можна очікувати через await
  • результат запиту доступний в об’єкті response
  • конструкція try...catch дозволяє обробляти помилки так само, як у звичайному синхронному коді

Обробка помилок

Axios генерує помилки у випадку проблем із мережею, або якщо відповідь від сервера має статус-код поза діапазоном 2xx. Об’єкт error містить детальну інформацію про те, що саме пішло не так:

import axios from 'axios';

async function fetchData() {
  try {
    const response = await axios.get('https://jsonplaceholder.typicode.com/unknown');
    console.log('Data:', response.data);
  } catch (error) {
    if (error.response) {
      // Сервер повернув статус-код, що не входить у діапазон 2xx
      console.error('Response error:', error.response.status, error.response.data);
    } else if (error.request) {
      // Запит був відправлений, але відповіді не отримано
      console.error('No response received:', error.request);
    } else {
      // Помилка під час налаштування запиту
      console.error('Error:', error.message);
    }
  }
}

fetchData();

// Output:
// Response error: 404 {}

Пояснення:

  • error.response – сервер надіслав відповідь із помилкою. Містить:
    • статус-код (status)
    • тіло відповіді (data)
    • заголовки (headers)
  • error.request – запит був відправлений, але відповіді не надійшло. Зазвичай це проблеми мережі, DNS, CORS або тайм-аут. На відміну від error.response, тут немає статус-коду та даних відповіді.
  • error.message – інші типи помилок, наприклад:
    • некоректний URL
    • неправильна конфігурація
    • внутрішня помилка Axios

Налаштування заголовків

Axios дозволяє передавати власні HTTP-заголовки разом із запитом. Це корисно для авторизації, керування форматами даних або встановлення спеціальних параметрів сервера:

import axios from 'axios';

async function createPost() {
  try {
    const response = await axios.post(
      'https://jsonplaceholder.typicode.com/posts',
      {
        title: 'Hello',
        body: 'World',
      },
      {
        headers: {
          'Content-Type': 'application/json',
          Authorization: 'Bearer token',
        },
      },
    );
    
    console.log('Post created:', response.data);
  } catch (error) {
    if (axios.isAxiosError(error)) {
      console.error('Axios error:', error.message);
    } else {
      console.error('Unexpected error:', error);
    }
  }
}

createPost();

Створення власного Axios-клієнта

Щоб не дублювати однакові налаштування (базову адресу, тайм-аут, заголовки) у кожному запиті, можна створити окремий клієнт за допомогою axios.create(). Такий клієнт легко перевикористовувати у всьому проєкті:

import axios from 'axios';

const api = axios.create({
  baseURL: 'https://jsonplaceholder.typicode.com',
  timeout: 5000,
  headers: { 'Content-Type': 'application/json' },
});

async function getPost(id) {
  try {
    const response = await api.get(`/posts/${id}`);
    return response.data;
  } catch (error) {
    console.error('Failed to fetch post:', error.message);
    return null; // або можна прокинути далі: throw error;
  }
}

async function createPost(body) {
  try {
    const response = await api.post('/posts', body);
    return response.data;
  } catch (error) {
    console.error('Failed to create post:', error.message);
    return null;
  }
}

// Використання функцій для роботи з API
(async () => {
  const post = await getPost(1);
  console.log('Post:', post);

  const newPost = await createPost({
    title: 'Hello',
    body: 'World',
    userId: 1,
  });
  console.log('New post:', newPost);
})();

У цьому прикладі один і той самий об’єкт api використовується для GET та POST запитів, без повторного визначення параметрів.

Перехоплювачі (Interceptors)

Перехоплювачі в Axios – це функції, які виконуються перед відправкою запиту або після отримання відповіді. Вони дозволяють централізовано додавати додаткову логіку: автоматично підставляти токени авторизації, логувати дані, обробляти помилки в одному місці тощо.

Зазвичай перехоплювачі налаштовують на створеному клієнті, щоб правила застосовувалися до всіх його запитів:

import axios from 'axios';

const api = axios.create({
  baseURL: 'https://jsonplaceholder.typicode.com',
});

Перехоплювач запитів:

api.interceptors.request.use(
  (config) => {
    // Наприклад, додати токен авторизації та логувати налаштування запиту
    config.headers.Authorization = 'Bearer my_token';
    console.log('Request:', config);
    return config;
  },
  (error) => Promise.reject(error),
);

Перехоплювач відповідей:

api.interceptors.response.use(
  (response) => {
    console.log('Response:', response);
    return response;
  },
  (error) => {
    console.error('Response error:', error);
    return Promise.reject(error);
  },
);

Після налаштування перехоплювачів вони виконуються автоматично для кожного запиту, що проходить через клієнт api:

async function getPosts() {
  const response = await api.get('/posts');
  return response.data; // Ніяких зайвих логів — перехоплювач уже все виведе
}

(async () => {
  const posts = await getPosts();
  console.log('Posts count:', posts.length);
})();

Скасування запитів

Іноді виникає потреба скасувати запит, який ще не завершився – наприклад, коли користувач переходить на іншу сторінку або швидко вводить текст у полі пошуку. Axios підтримує скасування через стандартний браузерний API AbortController.

Щоб скасувати запит, створюємо контролер і передаємо його signal у конфігурацію запиту:

import axios from 'axios';

const controller = new AbortController();

async function fetchData() {
  try {
    const response = await axios.get('https://jsonplaceholder.typicode.com/posts', {
      signal: controller.signal, // 1. Передаємо сигнал у конфігурацію
    });
    console.log('Дані отримано:', response.data);
  } catch (error) {
    // 3. Перевіряємо, чи помилка була викликана саме скасуванням
    if (axios.isCancel(error)) {
      console.log('Запит було скасовано');
    } else {
      console.error('Сталася помилка:', error);
    }
  }
}

fetchData();

// 2. Скасовуємо запит (наприклад, при зміні маршруту або натисканні кнопки)
setTimeout(() => {
  controller.abort();
}, 50);

Як це працює:

  1. Створюємо об’єкт AbortController.
  2. Передаємо controller.signal у налаштування Axios-запиту.
  3. Скасовуємо запит через controller.abort() у потрібний момент.
  4. У разі скасування Axios генерує помилку, яку можна визначити через axios.isCancel(error) – це дозволяє відрізнити її від інших типів помилок, таких як помилки сервера, тайм-аут або неправильна конфігурація запиту.

Підсумок

Axios – це простий і гнучкий HTTP-клієнт для JavaScript, який спрощує взаємодію з API завдяки зрозумілому синтаксису, підтримці власних клієнтів з конфігурацією та можливості використовувати перехоплювачі.

Основне, що варто пам’ятати:

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

Дивіться також допис про Fetch API – стандартний спосіб виконання HTTP-запитів у JavaScript.