[前端]Axios

鉴于目前我参与的项目大多数都使用Axios作为请求库,所以浅学一下也是有必要的

Steven-Zhl 头像
[前端]Axios
  • 这篇文章适合于有一定网络编程基础的人
  • 之后我们的用例全部基于TypeScript语法+Node.JS环境
  • 类比一下,Axios相当于Python中的requests,原生的http(Node.JS中)和XMLHttpRequests(浏览器中)就相当于urllib。虽然原生的不是不能用,但是Axios在各方面都更加方便:统一了不同环境中的网络API,Promise异步语法,以及诸如请求取消、拦截器等实用功能。

最简单的用例

import axios from 'axios';

// get
axios.get("https://steven-zhl.github.io").then(
    (resp) => console.log(resp.data)
).catch(
    (err) => console.log(err)
);

// post
axios.post("https://steven-zhl.github.io", {
    type: 'Test', content: 'This is a test'
}).then(
    (resp) => console.log(resp)
).catch(
    (err) => console.log(err)
);
  • 如上图所示,axios采用了Promise的链式调用API,其中then语句可以串联多个,表示上一步的函数执行完成后下一步执行的内容,而catch语句需要写在最后,当链式调用的then中任一步出现错误时,会调用catch中的回调函数。
  • 哦对,上述的Post请求会返回错误405 (Method Not Allowed),因为我的网站是用的Jekyll部署的,实际上全部为预编译好的静态文件,也只允许Get请求。

实例化和配置项

很多时候我们的请求都是针对同一个服务的,也就是同一个IP或域名,这时候我们可以实例化一个axios对象,然后在这个对象上进行请求,这样可以提高复用,减少代码冗余。

  • 实例化很简单,axios提供了create方法,可以直接创建一个对象:
import axios from "axios";

const service = axios.create()
service.get("https://steven-zhl.github.io").then(
    (resp) => console.log(resp.data)
).catch(
    (err) => console.log(err)
);
  • 我们刚刚说过,创建对象的目的通常是提高复用,但这看起来代码量也没有减少啊,其实到这儿还没完,通常实例化的同时会配合一些专属于该服务的配置。为此,我们接下来要介绍一下axios的配置项:

Axios配置

如果你去看看axios常用的几个函数的函数原型的话,会发现其中总会出现一个AxiosRequestConfig类型的参数,这就是Axios的配置项,在TS中通过这个接口规定了Axios的配置项。

  • 下面这一段是AxiosRequestConfig的部分定义,这里展示的几个配置项是最常用的。
export interface AxiosRequestConfig<D = any> {
  ....
  url?: string; // 请求的URL,可以是绝对路径,也可以是相对路径
  method?: Method | string; // 请求的方法,如'get'、'post'等
  baseURL?: string; // 常用于实例化对象的配置中,一旦配置,则请求的URL会自动拼接上这个前缀,url只需要写相对路径即可
  headers?: (RawAxiosRequestHeaders & MethodsHeaders) | AxiosHeaders; // 请求头
  params?: any; // 请求URL中的参数,实际上就是GET请求的参数,效果和在url参数里直接写效果一样
  timeout?: Milliseconds; // 超时时间,单位为毫秒
  ....
}
  • 上面的几个参数含义详见注释和文档吧,下面是一个简单的例子,展示了如何使用配置项:
import axios from "axios";
import * as fs from "fs";

const service = axios.create({
    baseURL: 'https://steven-zhl.github.io',
    timeout: 1000,
    headers: { 'Content-Type': 'application/json' }
})

service.get('/images/favicon.ico').then(
    (resp) => fs.writeFileSync('favicon.ico', resp.data);
).catch(
    (err) => console.log(err)
);
  • 在上述代码中,我们创建了一个针对steven-zhl.github.io,也就是我的博客的Axios对象,然后我们请求了/images/favicon.ico,即博客的Logo,并保存到本地。
  • 在代码中,由于baseURL的存在,我们只需要写相对路径即可,同时headers和timeout也都被作用于后续的其他请求。
  • 这个示例不够长,所以看起来不太明显,但当业务逻辑比较复杂时,这种方式可以很大程度减少代码冗余。