Axios или fetch
Как инструмент хождения из браузера на сервер - axios, fetch низкоуровен для такой цели.
Fetch — нативный низкоуровневый JavaScript интерфейс для выполнения HTTP-запросов с использованием обещаний через глобальный метод fetch()
.
Axios — JavaScript-библиотека, основанная на обещаниях, для выполнения HTTP-запросов.
В современных браузерах fetch
работает из коробки, для старых браузеров написаны полифилы, а библиотека это всегда дополнительные килобайты нагрузки.
GET запросы JSON данных
Типичная задача во frontend'е — получение JSON данных с сервера. Axios для этого требуется 1 действие, fetch - 2 действия: запрос + вызов метода .json()
над результатом запроса.
Fetch
fetch('https://jsonplaceholder.typicode.com/posts/1')
.then(response => response.json())
.then(json => console.log(json))
Axios
axios.get('https://jsonplaceholder.typicode.com/posts/1')
.then(response => console.log(response));
Обработка ошибок
Axios обрабатывает ошибки логично. Если сервер вернул ответ с HTTP статусом ошибки (например 404 или 500), то обещание будет отвергнуто.
axios.get(url)
.then(result => console.log('success:', result))
.catch(error => console.log('error:', error));
Fetch отвергнет обещание только если произошла сетевая ошибка (DNS не разрешил адрес, сервер недоступен, CORS не разрешен). В отстальных случаях ошибки не будет (включая HTTP статусы 404 или 500), поэтому для получения более интуитивного поведения такие ситуации придётся обрабатывать вручную.
fetch(url)
.then(response => {
return response.json().then(data => {
if (response.ok) {
return data;
} else {
return Promise.reject({status: response.status, data});
}
});
})
.then(result => console.log('success:', result))
.catch(error => console.log('error:', error));
Некоторые люди скажут: «В чем проблема? Вы запросили данные с сервера, и их получили. И если сервер ответил статусом 404, то это ответ сервера и точка.» На мой взгляд, для разработчика приложений, ответ сервера с кодом ошибки считается таким же исключением как сетевой сбой и должно обрабатываться соответствующим образом.
POST запросы
С axios
всё просто, а с fetch
уже не так: JSON обязан быть преобразован в строку, а заголовок Content-Type
должен указывать, что отправляются JSON данные, иначе сервер будет рассматривать их как строку.
Axios
axios.post('/user', {
firstName: 'Fred',
lastName: 'Flintstone'
});
Fetch
fetch('/user', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
firstName: 'Fred',
lastName: 'Flintstone'
})
});
Базовые значения для запросов
Как вы могли заметить, fetch
это явный API, вы ничего не получаете, если об этом не просите. Если используется аутентификация, основанная на сохранении сессии пользователя, то надо явно указывать куку. Если сервер расположен на поддомене, то надо явно прописывать CORS. Эти опции надо прописывать для всех вызовов сервера и у fetch
нет механизма для установки значений по-умолчанию, а у axios
есть.
axios.defaults.baseURL = 'https://api.example.com';
axios.defaults.headers.common['Accept'] = 'application/json';
axios.defaults.headers.post['Content-Type'] = 'application/json';
Заключение
Эквивалентный код
Axios
function addUser(details) {
return axios.post('https://api.example.com/user', details);
}
Fetch
function addUser(details) {
return fetch('https://api.example.com/user', {
mode: 'cors',
method: 'POST',
credentials: 'include',
body: JSON.stringify(details),
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'X-XSRF-TOKEN': getCookieValue('XSRF-TOKEN')
}
}).then(response => {
return response.json().then(data => {
if (response.ok) {
return data;
} else {
return Promise.reject({status: response.status, data});
}
});
});
}
Напрашивается написание функции-обёртку для работы с fetch
. Вероятно захочется взять её в следующий проект, а потом сделаеть на её основе свою http библиотеку. Затем сделать её более настраиваемой и получить аналог axios.
Безусловно, fetch
очень мощный современный механизм работы с http, но надо признать, что существуют более простые способы решать типовые задачи асинхронного получения ресурсов по сети.
Ссылки: