Axios和Fetch之间有什么区别?

334

我正在使用Fetch调用Web服务,但是我也可以使用Axios来做同样的事情。所以现在我感到困惑。我应该选择Axios还是Fetch?


6
我认为这个问题已经在https://github.com/mzabriskie/axios/issues/314上进行了详细讨论。 - Jaydeep Solanki
1
虽然有很多答案,但我发现没有人提到axiso相对于fetch的请求超时。 - Qiulang
Axios是为那些懒惰和未经训练的人准备的。 - morganney
12个回答

318
Fetch和Axios在功能上非常相似,但是为了更好的向后兼容性,Axios似乎工作得更好(例如,fetch在IE 11中无法工作,可以查看this post)。
另外,如果你使用JSON请求,以下是我遇到的一些区别。 Fetch JSON post请求
let url = 'https://someurl.com';
let options = {
            method: 'POST',
            mode: 'cors',
            headers: {
                'Accept': 'application/json',
                'Content-Type': 'application/json;charset=UTF-8'
            },
            body: JSON.stringify({
                property_one: value_one,
                property_two: value_two
            })
        };
let response = await fetch(url, options);
let responseOK = response && response.ok;
if (responseOK) {
    let data = await response.json();
    // do something with data
}

Axios JSON post请求

let url = 'https://someurl.com';
let options = {
            method: 'POST',
            url: url,
            headers: {
                'Accept': 'application/json',
                'Content-Type': 'application/json;charset=UTF-8'
            },
            data: {
                property_one: value_one,
                property_two: value_two
            }
        };
let response = await axios(options);
let responseOK = response && response.status === 200 && response.statusText === 'OK';
if (responseOK) {
    let data = await response.data;
    // do something with data
}

所以:
- Fetch的`body` = Axios的`data` - Fetch的`body`必须被`stringified`,Axios的`data`包含了`object` - Fetch的请求对象中没有`url`,Axios的请求对象中有`url` - Fetch的请求函数包括`url`作为参数,Axios的请求函数不包括`url`作为参数 - 当响应对象中包含`ok`属性时,Fetch的请求是`ok`的,Axios的请求在`status`为200且`statusText`为'OK'时是`ok`的 - 要获取JSON对象响应:在Fetch调用响应对象上的`json()`函数,在Axios中获取响应对象的`data`属性。

这里还有一个问题。一旦responseOk为true,我们需要检查response.data中是否提供了状态吗?谢谢。 - Yang Wang
7
当状态码为 200 且状态信息为 'OK' 时,Axios 请求是成功的。那么其他 2xx 范围内的状态码,比如 201 或者 204 呢? - leonbloy
我认为 response.ok 是一个布尔值,而 truefalse 的值表示响应是否正常。用户离线由 fetch() 拒绝处理,但其他类型的服务器错误由 response.ok 处理。 - nonopolarity

82

8
我仍然无法找到fetch比axios更有利的地方。你能否想到为什么我应该选择axios? - Gorakh Nath
4
我认为fetch是一个标准,可以参考https://fetch.spec.whatwg.org/...axios可能具有更多的功能,因为它没有遵循该标准...我认为最终它们都可以完成基本的工作(ajax http请求),但这取决于你的需求...我不需要转换器...所以选择标准库是优点... - Lucas Katayama
5
请注意,该表格是有误导性的。它将fetch定义为"原生"(意味着您可以直接使用它 - 无需包含任何库),但实际上在某些平台上并没有实现fetch(尤其是在所有版本的IE中),因此您仍需要提供外部polyfill。请参考此处链接以了解详情。 - Luca Fagioli
3
除了@jack123提到的差异外,fetch还缺乏基本的ajax功能,比如超时(这很奇怪),我们需要使用单独的模块来实现这个基本功能。 - Apurva jain
2
@LucasKatayama 链接似乎已经失效。 - vancy-pants
显示剩余9条评论

43

根据GitHub上mzabriskie

总体来说,它们非常相似。axios 的一些优点:

  • 转换器(Transformers):允许在请求发送之前或响应接收后对数据执行转换操作

  • 拦截器(Interceptors):允许您完全修改请求或响应(包括头信息)。同样,在请求发送之前或 Promise 解决之前执行异步操作

  • 内置XSRF保护

请检查 Axios 的浏览器支持情况。

browser support table

我认为你应该使用axios。


5
同意。Axios也足够小,导入起来不会有太多的负担 - 这与像Express或Mongoose这样的东西相反,如果一个人对包的大小有点疯狂,他们可能会感到担忧。 :) - CodeFinity

22

fetch API和axios API之间还有一个重要的区别

  • 使用Service Worker时,如果想拦截HTTP请求,必须仅使用fetch API
  • 例如,在使用Service Worker进行PWA缓存时,如果使用axios API,则无法缓存(它仅与fetch API配合工作)

7
有人能验证这是真的吗?虽然只有一个人发表了评论,但有9个赞同,看到评论会更好。(我在使用带有服务工作线程PWA离线功能的axios,所以我才问。) - Tom Stickel
当然,我们可以在这个问题上再加上一些评论,但是我在使用axios时遇到了缓存问题,当我用fetch() API替换axios时,问题得到了解决。 - Vaibhav KB
2
这似乎是正确的,但可能会在不久的将来修复: https://github.com/axios/axios/pull/2891 - arkhz

13
  1. Fetch API需要处理两个Promise才能获取JSON对象属性中的响应数据,而axios直接返回JSON对象。

  2. 在错误处理方面,fetch与axios不同,它在catch块中不能处理服务器端错误,即使响应是HTTP 404或500,从fetch()返回的Promise也不会拒绝HTTP错误状态。相反,它将正常解析(设置为假的ok状态),只有在网络故障或任何阻止请求完成时才会拒绝。而使用axios则可以在catch块中捕获所有错误。

我建议使用axios,直接处理拦截器、头部配置、设置cookie和错误处理。

参考此文


我认为这是最大的区别之一,感谢您澄清了这一点。 - Miguel Jara

12

Axios是一个独立的第三方包,可以通过NPM轻松安装到React项目中。

你提到的另一种选择是fetch函数。与Axios不同,fetch()已内置在大多数现代浏览器中。使用fetch时,您无需安装第三方包。

所以,由你决定,你可以使用fetch(),但如果你不知道自己在做什么,可能会出错,或者使用我认为更加简单的Axios。


2
Fetch没问题,但Axios就像你说的那样——更加简单明了。现代浏览器内置的Fetch对于功能发布来说并不是很好。因此我更喜欢Axios。 - Tom Stickel

11

axios的优点:

  • 转换器(Transformers):允许在请求发送前或响应接收后对数据进行转换
  • 拦截器(Interceptors):允许您完全改变请求或响应(包括头信息),也可以在请求发送前或Promise完成前执行异步操作
  • 内置XSRF保护

相比于fetch,axios的优势


5

此外...我在测试中尝试使用不同的库,并注意到它们对于4xx请求的处理方式不同。在这种情况下,我的测试返回一个带有400响应的JSON对象。以下是3个流行库处理此响应的方式:

// request-promise-native
const body = request({ url: url, json: true })
const res = await t.throws(body);
console.log(res.error)


// node-fetch
const body = await fetch(url)
console.log(await body.json())


// Axios
const body = axios.get(url)
const res = await t.throws(body);
console.log(res.response.data)

值得注意的是,request-promise-nativeaxios 在收到 4xx 响应时会抛出异常,而 node-fetch 则不会。此外,fetch 使用一个 promise 来解析 JSON。


1
@baitun 这些是我运行单元测试时的结果,我想我当时使用的是Mocha,通常会使用.throws方法来测试错误抛出。在这种情况下,我正在测试从所有3个库中拒绝的情况,并注意到返回的数据差异。 - cyberwombat

2
Axios是基于Promise的HTTP客户端库,而Fetch是用于进行API请求的JavaScript API。
其主要区别在于浏览器支持:Axios支持所有浏览器,包括IE,而Fetch仅被最新的浏览器支持,IE不支持它。
参考链接:https://github.com/axios/axios#browser-support

https://caniuse.com/fetch

Axios比fetch API具有更好的错误处理能力。Axios可以抛出400到500范围内的状态码错误,而在fetch API中,您需要手动处理这些错误。 了解更多信息:https://bariablogger.in/f/axios-vs-fetch-react

0

使用fetch时,需要处理两个Promise对象。使用axios时,可以直接访问响应对象data属性中的JSON结果。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接