Axios 和 Fetch的简要介绍和比较

当我们制做web应用时,我们通常使用AxiosFetch等客户端来执行网络请求。 本文将介绍并表AxiosFetch,以便在实际应用做出正确的选择。

AxiosFetch概述

Fetch API是一个提供了fetch()方法的用于发送网络请求的接口,它内置于现代浏览器中,因此无需安装。Axios是一个第三方库,我们可以通过cdn或包管理器安装使用它,Axios可以在浏览器或node.js中运行。
Fetchaxios都是基于promise的HTTP客户端,这意味着当使用它们发出网络请求时,它们会返回一个resolverejectpromise

安装axios

如果我们是在node.js环境下使用axios,我们可以使用以下任何一种方法安装axios

  1. 通过NPM安装:
npm install axios 
  1. 通过Yarn安装:
yarn add axios 

然后在项目中引入:

import axios from "axios"; 

如果是在浏览器中使用axios,我们可以通过cdn引入:

<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script> 

FetchAxios之间的比较

语法

Fetch接受两个参数。第一个参数是我们要获取的资源的URL。第二个是可选参数,一个配置选项的对象。因此,语法是: 如果没有配置选项,请求将默认为发出GET请求:

fetch(url) 

通过配置选项,我们可以为请求定义一些设置,包括:

 fetch(url, { 
    method: 'GET', // other options: POST, PUT, DELETE, etc. 
    headers: { 
        'Content-Type': 'application/json'
    }, 
    body: JSON.stringify({}), 
}) 

Axios语法类似,但有许多不同的调用方式:

axios(url, { 
    // configuration options 
}) 

我们还可以像这样附加HTTP方法:

axios.get(url, { 
    // configuration options 
}) 

与fetch方法一样,我们可以忽略axios中的HTTP方法,默认get方法:

axios(url) 

同样,我们可以使用第二个参数为请求定义一些自定义设置:

axios(url, { 
    method: 'get', // other options: post, put, delete, etc. 
    headers: {}, 
    data: {},
}) 

我们也可以这样写:

axios({ 
    method: 'get', 
    url: url, 
    headers: {}, 
    data: {}, 
}) 

处理JSON 数据

在下面的示例中,我们使用fetchAxios执行GET请求,以获取todos项的列表,并比较它们之间的差异。 使用Fetch API,我们的代码如下所示:

const url = "https://jsonplaceholder.typicode.com/todos"; 
fetch(url) 
    .then(response => response.json()) 
    .then(console.log); 

控制台中的结果如下所示:

image.png

fetch()返回一个promise,在.then方法里面处理,此时,我们还没有获得所需要的json格式的数据,所以在response对象上调用.json()方法,这将返回另一个以json格式数据resolvepromise,所以fetch请求包含两个promise

但是,如果我们使用Axios执行相同的请求,我们有以下代码:

const url = "https://jsonplaceholder.typicode.com/todos";

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

对于Axios,响应数据默认为JSON。响应数据在response对象的data属性上。

我们可以通过在配置项中指定responseType来覆盖默认的JSON数据类型,如下所示:

axios.get(url, { 
    responseType: 'json' // options: 'arraybuffer', 'document', 'blob', 'text', 'stream' 
}) 

自动字符串化

当我们用post方法向api接口发送js对象时,Axios会自动字符串化数据,以下代码使用Axios执行post请求:

 const url = "https://jsonplaceholder.typicode.com/todos"; 
    const todo = { title: "A new todo", completed: false } 
    axios.post(url, { 
    headers: { 
        'Content-Type': 'application/json',
        }
    , data: todo
    }) .then(console.log); 

当我们使用axios发出post请求时, 我们把请求主体数据分配给data属性。我们还可以设置Content-Type 。 默认情况下,axios将Content-Type设置为application/json。 让我们来看一下响应数据:

image.png

响应数据在response.data上:

.then(response => console.log(response.data));` 

如果我们使用Fetch API,我们必须使用JSON.stringify()手动字符串化对象,然后将其分配给请求主体。

 const url = "https://jsonplaceholder.typicode.com/todos"; 
    const todo = { title: "A new todo", completed: false }; 
    fetch(url, { 
        method: "post", 
        headers: { "Content-Type": "application/json" }, 
        body: JSON.stringify(todo) 
    })
    .then((response) => response.json())
    .then((data) => console.log(data)) 

使用fetch时我们还必须显式地将Content-Type 设置为application/json。

错误处理

fetch和axios都返回了一个resolvedrejectedpromise。 当promiserejected时,我们可以使用.catch()来处理错误。与Fetch方法相比,使用axios处理错误的方式更加简洁。
axios中,一个典型的错误使用.catch()处理是这样的:

 const url = "https://jsonplaceholder.typicode.com/todos"; 
    axios.get(url) 
    .then((response) => console.log(response.data)) 
    .catch((err) => { 
        console.log(err.message); 
    }); 

如果状态码超出2xx的范围,Axios的promise将被reject。我们可以通过查看err对象是否包含responserequest属性来获取有关错误的更多信息,如下所示:

.catch((err) => {
    // handling error
    if (err.response) {
        // Request made and server responded

        const {
            status,
            config
        } = err.response;

        if (status === 404) {
            console.log(`${config.url} not found`);
        }
        if (status === 500) {
            console.log("Server error");
        }
    } else if (err.request) {
        // Request made but no response from server
        console.log("Error", err.message);
    } else {
        // some other errors
        console.log("Error", err.message);
    }
}); 

error对象有response属性时表示客户端收到了状态码超出2xx范围的错误响应。error对象有request属性表示发出了请求,但客户端没有收到响应。否则,如果没有请求或响应属性,则说明出现网络错误。
如果出现404错误或其他HTTP错误,Fetch不会reject promise。Fetch仅在网络出现故障时reject promise。因此,我们必须在.then方法内手动处理HTTP错误。

const url = "https://jsonplaceholder.typicode.com/todos";

fetch(url)
    .then((response) => {
        if (!response.ok) {
            throw new Error(
                `This is an HTTP error: The status is ${response.status}`
            );
        }
        return response.json();
    })
    .then(console.log)
    .catch(err => {
        console.log(err.message);
    }); 

在响应块中,我们检查响应的ok状态是否为false,然后抛出一个在中处理的自定义错误。 我们可以看看响应对象上可用的方法,如下所示:image.png

上面的屏幕截图是成功的fetch。在遇到错误的URL地址的情况下,ok和status属性将分别变为false和404,我们抛出一个错误,因此.catch() 子句将显示自定义错误消息。

响应超时/取消请求

让我们看看这些HTTP客户端如何处理HTTP请求的响应超时。使用Axios,我们可以在配置对象中添加超时属性,并以毫秒为单位指定请求终止前的时间。 在下面的代码片段中,我们的目标是,如果请求超过四秒钟的时间,就终止请求,然后在控制台中记录错误。

const url = "https://jsonplaceholder.typicode.com/todos";

axios.get(url, {
        timeout: 4000, // default is `0` (no timeout)
    })
    .then((response) => console.log(response.data))
    .catch((err) => {
        console.log(err.message);
    }); 

要使用Fetch取消请求,我们可以使用AbortController接口。请参见下面的用法:

const url = "https://jsonplaceholder.typicode.com/todos";

const controller = new AbortController();
const signal = controller.signal;
setTimeout(() => controller.abort(), 4000);

fetch(url, {
        signal: signal
    })
    .then((response) => response.json())
    .then(console.log)
    .catch((err) => {
        console.error(err.message);
    }); 

我们从创建一个控制器对象开始,并获得了对signal对象和abort()方法的访问权。然后,我们通过配置选项将signal对象传递给fetch()。这样,只要触发了abort方法,fetch请求就会终止。我们可以看到,在setTimeout函数的帮助下,如果服务器在四秒钟内没有响应,操作就会终止。

效率表现

由于Fetch和axios都是基于promise的,因此它们不应该导致任何性能问题。然而,我们仍然可以使用measurethat.net来衡量他们的表现。我们得到以下结果:

image.png

如上所述,本机获取速度略快于axios。这是无关紧要的,因为两者都是异步的。

浏览器支持

Axios和Fetch在现代浏览器中得到广泛支持。对于像IE 11这样不支持ES6 promise的旧环境,对于Fetch,我们还需要添加一个polyfill来支持旧浏览器。

总结

我们讨论了Fetch和axios,并使用真实场景对它们进行了实际比较。最后,你在项目中选择什么取决于你的个人喜好和易用性。

measurethat.net/")来衡量他们的表现。我们得到以下结果:

[外链图片转存中…(img-DdkCA7wY-1653010293120)]

如上所述,本机获取速度略快于axios。这是无关紧要的,因为两者都是异步的。

浏览器支持

Axios和Fetch在现代浏览器中得到广泛支持。对于像IE 11这样不支持ES6 promise的旧环境,对于Fetch,我们还需要添加一个polyfill来支持旧浏览器。

总结

我们讨论了Fetch和axios,并使用真实场景对它们进行了实际比较。最后,你在项目中选择什么取决于你的个人喜好和易用性。


版权声明:本文为Android_boom原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。