Fetch与Axios - 猿码设计师https://www.yuanmadesign.com/ymdesign/axios-fetch
“ 在前端页面开发过程中,应该用fetch还是axios呢?比较出真知。”
在开始一个新的前端项目时,我一直争论的一件事是:应该使用 fetch API 吗?还是应该使用 Axios?在这里,我将描述每种工具之间的区别,以便您可以就使用哪些工具做出明智的决定。
让我们先回顾一下每个工具的基础知识,从 Fetch 开始。Fetch API 是一个内置的浏览器 API,用于从服务器获取数据。如果你有使用 XMLHttpRequest 的经验,那么这个 API 基本上就是它的简单版本。这是此 API 的示例代码。
fetch('http://example.com/game.json')
.then(response => response.json())
.then(data => console.log(data));
现在让我们谈谈Axios。与 Fetch API 一样,Axios 是一个用于从服务器获取数据的 NPM 库。如果 Fetch API 只能用在浏览器端,那么 Axios 既可以用在浏览器端,也可以用在服务器端。这是因为每一方获取数据的方法不同。在浏览器端,它使用 XMLHttpRequest。在服务器端,它使用 http 模块。这是此 API 的示例代码:
axios.get('/user?ID=019638').then(function (response) {
console.log(response.data);
});
请注意,Axios 需要使用单个Promise来获取数据主体,而 Fetch API 使用双重 Promise 样式。这是因为 Fetch API 在收到响应的阅读器后立即返回,然后 API 需要等到主体被加载,因此是双重Promise风格。
现在,让我们谈谈这两种工具的各个方面之间的区别,以下是我们从下面几个方面讨论:
- 总体功能比较
- 错误处理 – Error Handling
- 兼容性 – Compatibility
- 超时处理 – Timeout
- 拦截器 – Interceptor
01
—
总体功能
好的,让我们从一般差异开始。我们之前讨论过 Fetch API 使用双重Promise,而 Axios 只是一个单一的Promise。Axios 的单一Promise使其更适合Body不是那么大的用例。如果您的用例只是交换简单的 JSON 数据,那么 Axios 可能对您来说更方便。但是如果你要发送像图片这样的大数据,那么你可以试试 Fetch API 看看它是否适合你。
我们还可以填充 Fetch API,使其成为像 Axios 一样的单一 Promise 样式。下面的代码是 Fetch API 的单一承诺风格。
const fetchSimple = api => fetch(api)
.then(res => res.ok ? res : res.json()
.then(err => Promise.reject(err)));
fetchSimple('http://example.com/movies.json')
.then(response => response.json())
.catch(err => console.log(err));
另一个值得一提的是 Fetch API 是内置的,而 Axios 是一个额外的依赖项。如果您想让您的应用程序保持轻便,那么 Fetch API 可能更适合您。
02
—
错误处理 – Error Handling
在获取数据时,总是有可能引发一些错误。诸如无效凭证、未找到 URL 甚至服务器错误之类的错误,这些是必须处理的错误。在 Fetch API 中,要检查请求是否无效,我们可以通过查看 Response.ok 属性来检查。如果响应在 200–299 范围内,此属性将返回 true,否则返回 false。
var myImage = document.querySelector('img');
var myRequest = new Request('flowers.jpg');
fetch(myRequest).then(function(response) {
console.log(response.ok); // returns true if the response returned successfully
response.blob().then(function(myBlob) {
var objectURL = URL.createObjectURL(myBlob);
myImage.src = objectURL;
});
});
而对于 Axios,其错误处理类似于其他基于 Promise 的对象:使用 catch 处理程序。所有失败的请求都将被拒绝,并且可以使用此处理程序进行匹配。以下示例是来自 Axios 文档的官方示例。我们可以看到,在示例中,错误处理可以分为 3 类:
- 响应错误:状态代码超出 200–299 范围。
- 请求错误:发出请求但未收到响应。
- 其他类型的错误:无法发送请求。
axios.get('/user/12345')
.catch(function (error) {
if (error.response) {
// The request was made and the server responded with a status code
// that falls out of the range of 2xx
console.log(error.response.data);
console.log(error.response.status);
console.log(error.response.headers);
} else if (error.request) {
// The request was made but no response was received
// `error.request` is an instance of XMLHttpRequest in the browser and an instance of
// http.ClientRequest in node.js
console.log(error.request);
} else {
// Something happened in setting up the request that triggered an Error
console.log('Error', error.message);
}
console.log(error.config);
});
03
—
兼容性 – Compatibility
接下来,让我们讨论一下浏览器的兼容性。与 Fetch API 兼容性相比,Axios 与浏览器早期版本的兼容性要好得多。这是因为,在浏览器端,Axios 使用了 XMLHttpRequest。如果您在 XMLHttpRequest 文档中看到,此功能与早期浏览器版本兼容。这意味着当您使用 Fetch API 时,您必须了解它可能无法在某些早期版本上运行。在大多数情况下,这应该没有问题,因为没有多少人不更新他们的浏览器。
XMLHttpRequest Browser Compatibility
04
—
超时 – Timeout
当您的请求意外地需要太长时间来处理时,您可能希望提前结束它,以便用户知道有问题。为了实现这一点,我们需要在我们使用的获取工具中提供超时功能。在 Axios 中,这个功能已经存在。就像在请求配置中添加超时属性一样简单。
axios({
method: 'post',
url: '/user',
timeout: 4000 // Wait until 4 second before aborting
});
而对于 Fetch API,没有内置功能。但是在较新的浏览器版本中,我们可以使用一个名为 AbortControler 的界面。简单地说,AbortController 是一个接口,我们可以使用它来中止仍在运行的获取请求。该接口的示例用法如下所示。
const controller = new AbortController();
const signal = controller.signal;
fetch("https://example.com/movies.json", {
method: 'get',
signal: signal,
})
// ... (Other code)
controller.abort();
05
—
拦截器 – Interceptor
Axios 具有丰富的功能。在我看来,最重要的功能之一是拦截器功能。此功能将在运行之前拦截您的请求和响应。这可以用于许多事情,例如日志记录、挂钩调用或标题添加。拦截器的示例代码如下,取自 Axios 官方文档。
// Add a request interceptor
axios.interceptors.request.use(function (config) {
// Do something before request is sent
return config;
}, function (error) {
// Do something with request error
return Promise.reject(error);
});
// Add a response interceptor
axios.interceptors.response.use(function (response) {
// Any status code that lie within the range of 2xx cause this function to trigger
// Do something with response data
return response;
}, function (error) {
// Any status codes that falls outside the range of 2xx cause this function to trigger
// Do something with response error
return Promise.reject(error);
});
总的来说,我个人更喜欢在我的项目中使用 Axios,以其在项目中可能需要它们的附加功能。但是,如果您有一个特定的用例,您认为需要使用 Fetch API,那么请继续使用它。它们都是成熟的工具,当你有关于它们的问题时,你可以问很多人,所以选择任何一种工具都不会出错。