在我们之前的文章“如何使用 Axios 发出 HTTP 请求”中,我们已经解释了如何使用 Axios 发送基本的 CRUD 请求。使用 Axios 的主要好处之一是发送请求时自动进行 JSON 字符串化。本机Fetch API不支持的功能。
我们的帖子得出结论,Axios 是一个轻量级库,在处理 HTTP 请求时提供了许多有用的功能。例如,Axios 提供了一种通过其请求配置来跟踪上传进度的简单方法。此外,Axios 允许您定义拦截器以轻松地自动执行请求的特定任务。
不过,让我们也看看 Fetch API。您可以使用 Fetch API 执行相同的任务。最重要的是,Fetch API 已经在所有现代浏览器中可用。
本文旨在为您提供这两种工具的概述,以便您在选择发送 HTTP 请求的工具时做出更明智的决定。
我们会比较:
- CRUD 操作
- 自动 JSON 解析
- 拦截器
- 错误处理
- 请求超时功能
比较:CRUD 操作和自动 JSON 解析
我们先来看看发送基本请求。让我们从typicode.com上的公开 API 中检索一些数据。
首先,Axios 对象公开了不同的方法来从 API 中检索、发送、更新或删除资源。
axios.get(url[, config])
axios.post(url[, data[, config]])
axios.put(url[, data[, config]])
axios.patch(url[, data[, config]])
axios.delete(url[, config])
对于GET
请求,该函数接受 API URL 和可选配置对象。
const axios = require('axios')
const getRequest = async () => {
try {
const response = await axios.get('https://jsonplaceholder.typicode.com/todos/1');
console.log(response.data);
} catch (err) {
console.error(err);
}
}
getRequest()
config
对象来发送额外的参数或标头。您可以在 Axios 文档中找到所有可能的请求配置参数。
const response = await axios.get('https://jsonplaceholder.typicode.com/todos', {
params: {
ID: 1
},
headers: {'X-Custom-Header': 'foobar'},
});
fetch()
版本。fetch API 与 Axios API 相同。请注意,您可以通过对象将任何方法传递给fetch()
函数options
。
fetch(url, [options])
如您所见,它接受一个 API URL 和一个options
对象。我们必须通过选项对象传递方法。此外,我们还可以使用此对象传递标头、参数或正文。
const options = {
method: 'GET',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json;charset=UTF-8'
}
}
fetch('https://jsonplaceholder.typicode.com/todos/1', options)
.then(response => response.json())
.then(console.log)
比较:拦截器
Axios 为请求和响应提供了拦截器。换句话说,您可以在将请求发送到 API 之前对其进行修改,或者修改已返回的响应对象。这是一个强大的概念,可以实现特定任务的自动化。
您可以使用请求拦截器自动添加授权标头。此外,响应拦截器可用于修改响应对象以适应不同的格式。甚至可以拦截错误响应并将它们发送到监控工具。
这是我们之前教程中使用的 Axios 拦截器的示例。该axios.interceptors.request.use()
方法允许您定义请求拦截器。
axios.interceptors.request.use(config => {
config.name = 'my-axios-app'
console.log(`Sending ${config.method} request to: ${config.url}`);
return config;
}, error => {
return Promise.reject(error);
});
// send GET request
axios.get('https://jsonplaceholder.typicode.com/todos/1')
fetch()
?默认情况下,fetch()
不支持定义请求拦截器的方式。幸运的是,我们可以回退到覆盖函数,这样我们就可以向 fetch 方法添加自定义逻辑。
fetch = (originalFetch => {
return (...arguments) => {
console.log('Adding headers')
arguments[1].headers = {
'Accept': 'application/json'
}
return originalFetch.apply(this, arguments);
};
})(fetch);
fetch('https://jsonplaceholder.typicode.com/todos/1', { method: 'GET' })
.then(response => response.json())
.then(data => {
console.log(data)
});
fetch()
函数会影响代码的可读性。就个人而言,我更喜欢使用 Axios 的请求和响应拦截器。然而,有一个 NPM 包允许您以fetch()
更易读的方式将自定义拦截器注册到该方法。该包称为fetch-intercept。这是解决问题的示例。
const fetchIntercept = require('fetch-intercept')
const unregister = fetchIntercept.register({
request: function (url, config) {
// Modify the url or config here
console.log(`Sending ${config.method} request to: ${url}`);
return [url, config];
},
response: function (response) {
// Modify the reponse object
console.log('Response received')
return response;
}
});
// Call fetch to see your interceptors in action.
fetch('https://jsonplaceholder.typicode.com/todos/1');
// Unregister your interceptor
unregister();
比较:错误处理
fetch()
了解 Axios 和错误处理之间的区别很重要。当 Axios 收到 404 或 400 错误时,它会使用catch()
块捕获错误。此catch()
块允许您处理错误。
相反,Fetch API 更喜欢通过该方法成功完成请求,then()
但包含 400 状态。我们也可以在fetch()文档中找到它。
即使响应是 HTTP 404 或 500,从 fetch() 返回的 Promise 也不会拒绝 HTTP 错误状态。相反,它将正常解析(将 ok 状态设置为 false),并且只会在网络故障时拒绝或者如果有任何事情阻止请求完成。
您可以使用以下代码自己尝试一下。
const url = 'https://jsonplaceholder.typicode.com/toodoos/1'
axios.get(url)
.then(response => console.log('good'))
.catch(error => console.error('error')) // enters catch method -> prints 404
fetch(url, { method: 'GET' })
.catch(error => console.log('BAD', error))
.then(response => console.log('GOOD', response.status, response.statusText)); // enters then method -> prints 404 status
但是,知道何时使用两个库之一是一个显着的区别。
比较:如何使请求超时?
能够为请求定义超时可以防止您的应用程序挂起请求。这些挂起的请求会减慢您的应用程序或导致内存泄漏,因此非常危险。
正如Roberto Vitillo 所说,“现代应用程序不会崩溃;他们挂了。其主要原因之一是假设网络是可靠的。不是。”
那么,Axios 和 Axios 是如何fetch()
处理请求超时的呢?
首先,Axios 没有设置默认超时。因此,它依赖于浏览器的请求超时。在 Chrome 中,网络请求在 300 秒时超时。那太长了。让我们使用config
对象来改变它。下面的示例在 1000 毫秒的等待时间后中止请求。
const response = await axios.get('https://jsonplaceholder.typicode.com/todos/1', {
timeout: 1000
});
const controller = new AbortController();
const fetchPromise = fetch('https://jsonplaceholder.typicode.com/todos/1', { signal: controller.signal });
// Abort request using setTimeout
setTimeout(() => controller.abort(), 1000);
fetchPromise.then(response => {
// Finished request
console.log(response)
})
AbortController
并通过我们的config
对象将中止信号传递给fetch()
方法。一旦setTimeout()
计时器用完,它将调用abort()
控制器对象上的方法。这个中止调用会向我们的fetch()
调用发送中止信号。
同样,fetch()
选择更长的解决方法来实现请求超时。
结论
Axios 提供了比fetch()
. 使用的最大缺点fetch()
是为您的请求设置超时的详细解决方法。这是防止挂起请求的急需功能。
另一方面,请记住 Axios 将默认超时设置为零。因此,不要忘记为每个请求设置超时。或者,您可以使用请求拦截器来自动设置请求超时。
此外,特别是对于 Node.js,自动 JSON 解析是一个有用的功能,可以让您的代码保持干净。同样,您可以使用 Fetch API 的拦截器将响应对象自动解析为 JSON。
然而,正如本指南中所见,我们必须覆盖fetch()
添加自定义逻辑的方法。我认为它增加了代码的复杂性。出于这个原因,Axios 是基于其简单性和易用性发送 HTTP 请求的明显赢家。