Хватит использовать Fetch API в JavaScript

Перед разработчиком нередко встает вопрос, какие использовать пакеты, инструменты и способы реализации задуманного. К примеру, каким способом стоит создавать HTTP-запросы? В данной статье я расскажу о библиотеке Axios и Fetch API, попутно продемонстрировав их отличия.

О чем вообще речь?

Когда требуется осуществлять информационный обмен с серверами через HTTP, мы отправляем запросы и получаем в ответ данные  —  этот процесс называется AJAX (асинхронный JavaScript и XML). Два самых известных ключевых слова, которые любой фронтенд-разработчик держит в арсенале для выполнения данной операции  —  это Axios и Fetch. 

Axios

Axios — это библиотека JS, используемая для отправки HTTP-запросов из Node.js либо браузера. В документации указаны следующие ее возможности:

  • Использование XMLHttpRequests из браузера;
  • Выполнение HTTP запросов из Node.js;
  • Поддержка Promise API;
  • Перехват запроса и ответа;
  • Преобразование данных запроса и ответа;
  • Отмена запросов;
  • Автоматическое преобразование для данных в формате JSON;
  • Клиентская поддержка защиты от XSRF (межсайтовая подделка запросов).

Поскольку библиотека Axios не является нативной для JavaScript API, ее необходимо импортировать в проект. Поэтапную инструкцию установки можете найти здесь.

Fetch API

Fetch API предоставляет интерфейс для получения ресурсов из браузера. Согласно документации, Fetch дает общее определение объектов для запроса и ответа. Этот API также использует промисы и предоставляет глобальный метод fetch(). Данный метод требует в качестве необходимого аргумента только путь к нужному ресурсу. В ответ он возвращает промис, который разрешает ответ на этот запрос, независимо от того, успешен он был или нет. 

Совместимость

Вот список ведущих браузеров, поддерживающих эти инструменты:

  • Axios — Chrome, Firefox, Safari, Opera, Edge, IE.
  • Fetch — Chrome, Firefox, Safari, Opera, Edge.

Можно смело сказать, что Axios отлично поддерживается в старых версиях браузеров, а также в IE, при том что Fetch API нет. 

Безопасность

Axios является менее уязвимым, поскольку предоставляет защиту от XSRF на клиентской стороне. Как правило, такие атаки происходят в ситуациях, когда HTTP-запрос совершается между сайтами с целью выдать злоумышленника за истинного пользователя. Более подробно об этом виде атак можно прочесть в Википедии.

Синтаксис

При сравнении Axios и Fetch важно отметить, что они сильно отличаются в своем синтаксисе. Возьмем, к примеру, метод GET:

const url = 'https://jsonplaceholder.typicode.com/posts';

// Axios
axios.get(url)
  .then(response => console.log(response));

// Fetch
fetch(url)
  .then(response => response.json())
  .then(data => console.log(data));

Если вы с этими инструментами еще не сталкивались, то наверняка поинтересуетесь, почему в случае Fetch использован метод .json(). По факту то же самое происходит в Axios внутренне при выполнении автоматической сериализации в JSON после разрешения запроса.

Прерывание запросов и ответов

HTTP-перехватчики отлично подходят для проверки HTTP-запросов, передаваемых от клиента серверу. Они хороши для изменения запросов/ответов до момента их начала/получения. В Fetch нет способа перехвата HTTP-запросов, но есть возможность обойти это ограничение переопределением глобального метода fetch() и созданием его собственного перехватчика.

При этом в Axios уже есть встроенный перехватчик, который выполняется даже до промисов .then или .catch. Продемонстрирую:

axios.interceptors.request.use(
  config => {
    // Здесь можно выполнить нужные действия с данными запроса
    console.log('A request has been sent!');
    return config;
  }, (error) => {
    return Promise.reject(error);
  }
);

axios.interceptors.response.use(
  config => {
    // Здесь можно выполнить нужные действия с данными ответа
    console.log('A response has been received!');
    return config;
  }, (error) => {
    return Promise.reject(error);
  }
);

axios.get('https://jsonplaceholder.typicode.com/posts')
  .then(response => console.log(response));

Таймаут и прогресс запроса

Одно из действительно крутых преимуществ Axios в том, что Fetch не предоставляет среди своих настроек timeout, определяющий временное ограничение, по истечении которого запрос отменяется. Таймаут является возможной опцией, передаваемой в объект config и измеряется в миллисекундах. Важно помнить, что таймаут относится к ответу, а не соединению. Например:

axios.get(
'https://jsonplaceholder.typicode.com/posts',
{
timeout: 10
}
)
.then(response => console.log(response));

Однако есть способ создать таймаут и с помощью Fetch API:

const controller = new AbortController();
const timeoutValue = 10000;
const timeout = setTimeout(() => controller.abort(), timeoutValue);
fetch('https://jsonplaceholder.typicode.com/posts', { signal: controller.signal })
.then(response => response.json())
.then(data => console.log(data));

Что касается прогресса, то и здесь есть очередной повод предпочесть Axios, поскольку он предоставляет более простой способ узнать о прогрессе запроса. Одной из опциональных настроек, передаваемой для этого в объект конфигурации, является OnUploadProgress.

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

С помощью Axios обрабатывать ошибки проще, поскольку плохие ответы автоматически отвергаются в отличие от Fetch, где даже 404 или 500 ошибки все равно обрабатываются. В случае, когда сервер возвращает код “500 Internal Server Error”, Fetch обработает его аналогично коду “200 OK”. Для решения этой проблемы можно использовать флаг “ok”:

fetch('https://official-joke-api.appspot.com/jokes/ten/hehe')
.then(response => {
if (!response.ok) {
throw Error(response.statusText)
}
return response.json()
})
.then(data => {
console.log(data)
})
.catch(error => console.error(error))

В случае же Axios простой пример обработки ошибки будет таким:

axios
.get('https://official-joke-api.appspot.com/jokes/ten/hehe')
.then(response => {
console.log("response", response)
})
.catch(error => console.log(error))

Заключение

Из рассмотренного материала очевидно, что Axios проще использовать, чем Fetch. Однако при этом также стоит учесть, что Axios является внешним пакетом, который потребуется включать в проект дополнительно. Fetch же изначально встроен в браузер, то есть дополнительного места не займет. Лично я предпочитаю использовать Axios, но это нельзя назвать правилом, так что окончательный выбор за вами. Делайте его с умом!

Ссылки

axios/axios
Promise based HTTP client for the browser and node.js New axios docs website: click here Make XMLHttpRequests from the…github.com
Fetch API — Web APIs | MDN
The Fetch API provides an interface for fetching resources (including across the network). It will seem familiar to…developer.mozilla.org

Читайте также:

Читайте нас в TelegramVK и Яндекс.Дзен


Перевод статьи Harsha Vardhan: Stop Using the Fetch API in JavaScript

Предыдущая статьяWebAssembly на Golang с нуля