前言

要了解axios,需要先了解Ajax(Asynchronous JavaScript And XML 即异步 JavaScript 和 XML)请求。简单来说,Ajax的作用为从服务端获取数据,实现页面的局部刷新。

一般请求和Ajax请求:

  • 一般请求:浏览器会直接显示响应体数据,会自动刷新整个网页或跳转页面。
  • Ajax请求:浏览器不会对整个界面进行刷新,得到数据后,对部分的元素进行刷新。

显然,Ajax请求减少了页面频繁刷新的次数,使用者的体验更加丝滑。Axios也是用来发送Ajax请求。

Axios 是一个流行的基于 Promise 的 HTTP 请求库,用于在浏览器和 Node.js 中进行 HTTP 请求。它提供了简单易用的 API,可以发送各种类型的请求(如 GET、POST、PUT、DELETE等),并处理响应数据,Axios 在前端工程化项目中有 99% 的概率会被优先选择。

Axios中文文档 | Axios中文网 (axios-http.cn)

演示API文档

后续演示使用的api文档,api文档的制作可以参考apiDoc

请求url 方式 参数
http://127.0.0.1:5000/persons GET 无需参数
http://127.0.0.1:5000/person GET query参数
id:String 人员唯一标识符
http://127.0.0.1:5000/filter/age GET parms参数
age:int 人员年龄
http://127.0.0.1:5000/person POST 请求体参数
name:string 名字
age:number 年龄
http://127.0.0.1:5000/person PUT 请求体参数
id:string 人员唯一标识符
name:string 人员名字
age:number 人员年龄
http://127.0.0.1:5000/person DELETE 请求体参数:
id:string 人员唯一标识符

模拟服务端使用的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
import Koa from "koa";
import Router from "@koa/router";
import Cors from "@koa/cors";
import { bodyParser } from "@koa/bodyparser";

const app = new Koa();
const hostname = "127.0.0.1";
const port = 5000;

app.use(Cors());
app.use(bodyParser({
// 一定记得添加允许请求的方法
parsedMethods: ["POST", "PUT", "PATCH", "DELETE", "GET"],
}));


let idList = ["0957c786", "00ad48e5", "a80ee35a", "14bff5f7"];

let students = [
{ id: "d93d5860", name: "Alice", age: 18 },
{ id: "a2f7d296", name: "Bob", age: 18 },
{ id: "d28403fa", name: "Charlie", age: 20 },
{ id: "2acbcc70", name: "David", age: 19 },
];

const router = new Router();

// 获取所有人 无参数
router.get("/persons", async (ctx) => {
const res = {
status: 1,
message: "success",
data: students,
};

// ctx.set("Access-Control-Allow-Origin", "*");
ctx.body = res;
});

// 获取一个人 query参数
router.get("/person", async (ctx) => {
const id = ctx.query.id;
console.log("id:", id);
const student = students.find((student) => student.id === id);
let res;
if (student) {
res = {
status: 1,
message: "success",
data: student,
};
} else {
res = {
status: 1,
message: "The student was not found",
};
}

ctx.body = res;
});

// 获取一堆人 params参数
router.get("/filter/:age", async (ctx) => {
const age = ctx.params.age;
const student = students.filter((student) => student.age === age);
let res;
if (student.length > 0) {
res = {
status: 1,
message: "success",
data: student,
};
} else {
res = {
status: 1,
message: "The student was not found",
};
}
ctx.body = res;
});

// 添加一个人 请求体参数
router.post("/person", async (ctx) => {
const body = ctx.request.body;
const id = idList[Math.floor(Math.random() * idList.length)];
idList.slice(idList.indexOf(id), 1);
let student = {
// 随机选择一个id
id: id,
name: body.name,
age: body.age,
};

students.push(student);

let res = {
status: 1,
message: "add success",
data: student,
};

ctx.body = res;
});

router.put("/person", async (ctx) => {
const body = ctx.request.body;
const id = body.id;
const student = students.find((student) => student.id === id);
let res;

if (student) {
// 根据id找到学生 然后修改name和age
student.name = body.name;
student.age = body.age;
// students.push(student);
res = {
status: 1,
message: "update success",
data: student,
};
} else {
res = {
status: 0,
message: "student not found",
};
}
ctx.body = res;
});

router.delete("/person", async (ctx) => {
const body = ctx.request.body;
const id = body.id;
// console.log("body:",body);
const student = students.find((student) => student.id === id);
// console.log(student);
let res;
if (student) {
students = students.filter((student) => student.id !== id);
res = {
status: 1,
message: "delete success",
data: id,
};
} else {
res = {
status: 0,
message: "student not found",
};
}

ctx.body = res;
});

app.use(router.routes());

app.use(async (ctx) => {
if (!ctx.body) {
ctx.status = 404;
ctx.body = "404 Not Found";
}
});

app.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});

初始数据为

1
2
3
4
5
6
[
{ id: "d93d5860", name: "Alice", age: 18 },
{ id: "a2f7d296", name: "Bob", age: 18 },
{ id: "d28403fa", name: "Charlie", age: 20 },
{ id: "2acbcc70", name: "David", age: 19 },
];

基本使用

引入cdn

1
<script src="https://cdn.bootcdn.net/ajax/libs/axios/1.7.5/axios.min.js"></script>

创建一个页面,并获取所有人的数据。地址为/persons

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://cdn.bootcdn.net/ajax/libs/axios/1.7.5/axios.min.js"></script>
</head>
<body>
<h1>axios的使用</h1>
<button onclick="getData()">获取数据</button>
<script>
function getData() {
// 填充获取数据的代码
}
</script>
</body>
</html>

axios有两种写法:

  • 简写形式:axios.get(url)
  • 一般形式:axios({method:"GET",url:url})
1
2
3
4
5
6
7
8
9
10
async function getData() {
// 简写形式
let result = await axios.get("http://127.0.0.1:5000/persons")

// 一般形式
let result = await axios({
method: 'get',
url: 'http://127.0.0.1:5000/persons'
})
}

axios返回的是一个Promise对象(也可以使用.then().catch()的写法,推荐异步async写法),其中包含请求的很多数据,我们需要的数据在data字段中。

image-20240829101731890

按照文档(也可参照上图),服务器返回的内容也是一个对象,其中包含多种信息,真实的数据在返回对象的data字段中。所以,如果要获取到真实数据,需要使用result.data.data

1
2
3
4
5
6
7
8
9
10
11
12
13
async function getData() {
// 简写形式
// let result = await axios.get('http://127.0.0.1:5000/persons')
// console.log(result);

// 一般形式
let result = await axios({
method: 'get',
url: 'http://127.0.0.1:5000/persons'
})

console.log("响应成功:",result.data.data);
}

这样就可以得到真实的数据。

image-20240829102126787

拦截器

拦截器是用来对请求和响应进行过滤、预处理的操作函数。具体原理图如下所示

image-20240829113114107

请求拦截器

考虑到api文档中所有的请求都以http://127.0.0.1:5000作为开头,因此可以考虑用请求拦截器优化这个行为。

参考上文拦截器的原理示意图,使用拦截器interceptors时,我们需要传入本次请求的信息config,并需要从拦截器中返回处理后的config,否则就会请求错误。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 请求拦截器
axios.interceptors.request.use((config) =>{
// 在发送请求之前做些什么
config.baseURL = 'http://127.0.0.1:5000'
return config;
})

async function getData() {
// 简写形式
let result = await axios.get('/persons')
console.log(result);

console.log("响应成功:",result.data.data);
}

使用baseURL设置后,所有的请求都会自动加上这个前缀,避免了多次重复书写的麻烦。

请求拦截器config的设置,可以在请求配置中找到。

响应拦截器

每次获取到数据都需要result.data.data,第一个data是由于axios本身造成的,且每次操作都一致,因此考虑使用相应拦截器来优化。

严格来说,请求是没有失败一说的,但是响应是有可能失败的。对与响应拦截器,还提供了一个回调函数供给出错处理使用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 相应拦截器
axios.interceptors.response.use(
(res)=>{
// 对响应数据做点什么
console.log("请求成功");
return res.data
},
(err)=>{
// 对响应错误做点什么
console.log("请求失败", err);
return err
}
)

async function getData() {
// 简写形式
let result = await axios.get('http://127.0.0.1:5000/persons')

console.log("响应成功:", result.data);
}

这样处理后,每次只需根据api文档的要求获取相应对象的字段即可,展示在上述代码中即为只需写一个data。

另外,使用await关键字有一个弊端,如果响应失败,且在拦截器中返回了具体的内容的话,那么会出现完全矛盾的输出。修改请求为/person2(实际并不存在这个api),控制台得到如下的结果。

image-20240829110233823

即便是响应失败了,还是让最后打印数据的语句执行了,这说明await得到了一个非reject的回应(代码返回的是err),因此程序正常执行了下去。可想而知,需要在错误处理和返回值的地方下手解决。

最简单的方法就是不写错误响应的回调函数,这样await迟迟等不来结果,就会抛出Uncaught (in promise) 的错误。但是这种方法无法得到任何语义化的提示,因此不是很推荐。

接下来介绍三种常用的处理方法。

  • 使用tryandcatch进行错误捕获。(在拦截器return err的情况下才有效)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    async function getData() {
    try {
    // 简写形式
    let result = await axios.get('/persons2')

    console.log("响应成功:", result.data);
    } catch (error) {
    console.log("响应失败", error);
    }
    }
  • Promise.reject 在拦截器中返回reject

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    // 添加响应拦截器
    axios.interceptors.response.use(
    res=>{
    // 对响应数据做点什么
    console.log("请求成功");
    return res.data
    },
    err=>{
    // 对响应错误做点什么
    console.log("请求失败");
    return Promise.reject(err)
    }
    )

    async function getData() {
    // 简写形式
    let result = await axios.get('/persons2')
    console.log("响应成功:",result.data);
    }
  • 中断Promise

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    // 添加响应拦截器
    axios.interceptors.response.use(
    res=>{
    // 对响应数据做点什么
    console.log("请求成功");
    return res.data
    },
    err=>{
    // 对响应错误做点什么
    console.log("请求失败");
    return new Promise(()=>{})
    }
    )

    async function getData() {
    // 简写形式
    let result = await axios.get('/persons2')
    console.log("响应成功:",result.data);
    }

全局axios配置

除了使用相应拦截器来规定默认的请求条件,也可以通过修改axios的全局配置项来实现。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
axios.defaults.baseURL = 'http://127.0.0.1:5000'
axios.defaults.timeout = 3000
axios.defaults.headers = {
"Content-Type":"application/json"
}

async function getData() {

// 简写形式
// let result = await axios.get('/filter/18')

// 完整形式
let result = await axios({
url:"/persons",
method:"get"

})

console.log("响应成功:",result);
// console.log(axios.defaults);
}

这样和前文中相应拦截器的效果是相同的,不同在于修改config的时机。

  • interceptors.request - 发出请求后在拦截器中修改,属事后修改。
  • axios.defaults - 在发出请求前就已经配置,属事前修改。
  • 后续创建的axios对象的设置会继承axios.defaults的值(非引用)。
  • 全局是针对只有一个axios的情况,新创建的axios不会因默认axios.default的修改受到影响。

请求类型和请求参数

常用的请求类型:

类型 常用领域 axios形式
GET axios#get(url[, config])
POST axios#post(url[, data[, config]])
PUT axios#put(url[, data[, config]])
DELETE axios#delete(url[, config])

请求参数类型:

  1. query参数(查询字符串)
  2. params参数(路径传参)
  3. 请求体参数(json编码,urlencoded编码)
  • GET请求无法携带请求体参数,其他的请求方法可以和参数类型随意组合

  • 各种请求的axios写法和参数,参考Axios 实例请求配置

GET请求

GET请求多用于查询场景。

query参数

id获取数据为例子。地址为/person

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
async function getData() {

// 简写形式 拼接字符串参数
// let result = await axios.get('/person?id=d93d5860')

// 简写形式 配置项参数
let result = await axios({
url:'/person',
method:'get',
params:{
id:'d93d5860'
}
})

console.log("响应成功:",result);
}

需要注意的是,设置query参数的名称为params,这是因为params本身就有参数的意思,最终可以得到相应的结果

1
2
3
4
5
6
7
8
9
{
"status": 1,
"message": "success",
"data": {
"id": "d93d5860",
"name": "Alice",
"age": 18
}
}

如果替换为不存在的id,那么不会返回data字段

1
2
3
4
{
"status": 1,
"message": "The student was not found"
}

使用配置项传参,实际上是axios自动将paramsbaseURL拼接好。在控制台可以看到具体的请求url。

image-20240829131459175

params参数

age获取数据为例子。地址为/filter/age

params参数也称为路径传参。需要注意的是,params传参不存在配置项的写法

1
2
3
4
5
6
7
8
9
10
11
12
13
async function getData() {

// 简写形式
// let result = await axios.get('/filter/18')

// 完整形式
let result = await axios({
url:"/filter/18",
method:"get"
})

console.log("响应成功:",result);
}

得到的返回结果如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
{
"status": 1,
"message": "success",
"data": [
{
"id": "d93d5860",
"name": "Alice",
"age": 18
},
{
"id": "a2f7d296",
"name": "Bob",
"age": 18
}
]
}

如果输入age匹配不到,不会返回data字段

1
2
3
4
{
"status": 1,
"message": "The student was not found"
}

POST请求

POST请求主要用于添加数据。以添加用户为例子,地址为/person

使用的是请求体参数,有两种格式:

  • json格式 - {name:"强哥",age:28}(自动解析)
  • urlencoded格式 - "name=强哥&age=28"

简写形式

1
2
3
4
5
6
7
async function addData() {
// 简写形式 json格式
let result = await axios.post('/person',{name:"强哥",age:28})
// 简写形式 urlencoded格式
let result = await axios.post('/person',"name=强哥&age=28")
console.log("添加成功:",result);
}

完整形式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
async function addData() {
// 完整形式
let result = await axios({
url:"/person",
method:"post",
// json格式
data:{
name:"强哥",
age:28
}
// urlencoded格式
// data:"name=强哥&age=28"
})
console.log("添加成功:",result);
}

两种格式都能够成功添加

1
2
3
4
5
6
7
8
9
{
"status": 1,
"message": "add success",
"data": {
"id": "a80ee35a",
"name": "强哥",
"age": "28"
}
}

在控制台的负载面板中可以看到上传的请求体参数。

image-20240829133600177

查看所有人,可以看到人数加1,且能够看到添加的数据。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{
"status": 1,
"message": "success",
"data": [
{
"id": "d93d5860",
"name": "Alice",
"age": 18
},
// 中间3条数据省略
{
"id": "0957c786",
"name": "强哥",
"age": "28"
}
]
}

使用json作为请求体参数时,由于json不属于简单请求Content-Type的范围(urlencoded在范围内),因此请求为复杂请求,如果服务端没处理好,很有可能会遇到跨域问题。如果请求体参数以json格式发送,在开发者工具的网络面板中,可以看到预检请求(OPTIONS),具体的原因与解决方法参考前端-跨域&解决方案

image-20240829134257414

PUT请求

PUT请求主要用于更新数据。以修改信息为例。地址为/person

完整形式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
async function updateData() {
// 完整形式
let result = await axios({
url:"/person",
method:"put",
// json格式
data:{
id:"d93d5860",
name:"强哥",
age:500
},
// urlencoded格式
// data:"id=d93d5860&name=强哥&age=500"
})
console.log("修改成功:",result);
}

简写形式

1
2
3
4
5
6
7
async function updateData() {
// 简写形式 json格式
let result = await axios.put('/person',{id:"d93d5860",name:"强哥",age:500})
// 简写形式 urlencoded格式
// let result = await axios.put('/person',"id=d93d5860&name=强哥&age=500")
console.log("修改成功:",result);
}

控制台得到的返回为:

1
2
3
4
5
6
7
8
9
{
"status": 1,
"message": "update success",
"data": {
"id": "d93d5860",
"name": "强哥",
"age": 500
}
}

获取所有人数据,证实已被修改。

1
2
3
4
5
6
7
8
9
10
11
12
{
"status": 1,
"message": "success",
"data": [
{
"id": "d93d5860",
"name": "强哥",
"age": 500
},
// 其他省略
]
}

DELETE请求

PUT请求主要用于删除数据。以珊瑚信息为例。地址为/person

简写形式

1
2
3
4
5
6
7
8
9
async function delData() {

// 简写形式 json格式
let result = await axios.delete('/person',{data:{id:"d93d5860"}})
// 简写形式 urlencoded格式
let result = await axios.delete('/person',{data:"id=d93d5860"})

console.log("删除成功:",result);
}

完整形式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
async function delData() {
// 完整形式
let result = await axios({
url:"/person",
method:"delete",
// urlencoded格式
data:{
id:"d93d5860"
},
// json格式
// data:"id=d93d5860"
})

console.log("删除成功:",result);
}

返回的结果如下

1
2
3
4
5
{
"status": 1,
"message": "delete success",
"data": "d93d5860"
}

查看原始数据,发现确实少了id为d93d5860的数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
{
"status": 1,
"message": "success",
"data": [
{
"id": "a2f7d296",
"name": "Bob",
"age": 18
},
{
"id": "d28403fa",
"name": "Charlie",
"age": 20
},
{
"id": "2acbcc70",
"name": "David",
"age": 19
}
]
}

创建axios

假设需要访问多个不同的api源。除了http://127.0.0.1:5000,我们还需要访问另一个热搜榜的apihttps://tenapi.cn/v2。那么就需要多个axios对象。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
const axios2 = axios.create({
baseURL:"https://tenapi.cn/v2",
timeout:3000,
headers:{
"Content-Type":"application/json"
}
})

axios.defaults.baseURL = "http://127.0.0.1:5000"

async function getAllPerson() {
let result = await axios.get("/persons")
console.log(result);
}

async function getHotData(){
let result2 = await axios2.get("/bilihot")
// console.log(result2);
console.log(result2.data.data);
}

async function getZhiData(){
let result3 = await axios2.get("/zhihuhot")
console.log(result3.data.data);
}

上述代码创建了一个新的axios对象用于获取热搜数据,将其baseURL设置为https://tenapi.cn/v2,而保留原本的axios用于本地http://127.0.0.1:5000的请求。这样两者就不会发生冲突。

注意:

  • 创建的axios会继承axios.defaults里的所有配置项,因此需要单独重新设定配置项(否则配置项完全相同)。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    axios.defaults.baseURL = 'http://127.0.0.1:5000'
    axios.defaults.timeout = 5000

    // 未配置的axios实例 与默认axios的配置完全相同
    const axios2 = axios.create()

    function isEqual(obj1, obj2) {
    const keys1 = Object.keys(obj1);
    const keys2 = Object.keys(obj2);

    if (keys1.length !== keys2.length) {
    return { result: false, message: "长度不相等" };
    }

    for (let key of keys1) {
    if (!obj2.hasOwnProperty(key)) {
    return { result: false, message: "缺少属性" };
    }

    if (
    typeof obj1[key] === "object" &&
    obj1[key] !== null &&
    typeof obj2[key] === "object" &&
    obj2[key] !== null
    ) {
    const subResult = isEqual(obj1[key], obj2[key]);
    if (!subResult.result) {
    return subResult;
    }
    } else if (obj1[key] !== obj2[key]) {
    return { result: false, message: "值不相等" };
    }
    }

    return { result: true, message: "完全相同" };
    }

    console.log(isEqual(axios.defaults, axios2.defaults)); // { result: true, message: "完全相同" }
  • 新创建的axios没有取消请求和批量发请求的方法,其它语法完全一致。

批量发送请求

可以将多个axios对象放在一个列表中,使用axios.all()一次性发出全部请求。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
axios.defaults.baseURL = 'http://127.0.0.1:5000'
axios.defaults.timeout = 5000

const axios2 = axios.create()

axios2.defaults.baseURL= 'https://tenapi.cn/v2'

async function getAllData(){
let result = await axios.all([
axios({ url: "/persons", method: "get" }),
axios({ url: "/filter/18", method: "get" }),
axios2({ url: "/bilihot", method: "get" }),
]);

console.log(result);
}

返回的是装有所有响应请求对象的数组,如下所示(为了展示删除了对象的一些属性)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
[
{
"data": {
"status": 1,
"message": "success",
"data": [
{
"id": "d93d5860",
"name": "Alice",
"age": 18
},
{
"id": "a2f7d296",
"name": "Bob",
"age": 18
},
{
"id": "d28403fa",
"name": "Charlie",
"age": 20
},
{
"id": "2acbcc70",
"name": "David",
"age": 19
}
]
},
"status": 200,
"statusText": "OK",
"headers": {
"content-length": "209",
"content-type": "application/json; charset=utf-8"
},
},
{
"data": {
"status": 1,
"message": "The student was not found"
},
"status": 200,
"statusText": "OK",
"headers": {
"content-length": "50",
"content-type": "application/json; charset=utf-8"
},

},
{
"data": {
"code": 200,
"msg": "success",
"data": [
{
"name": "周杰伦败诉网易",
"url": "https://search.bilibili.com/all?vt=36849326&keyword=%E5%91%A8%E6%9D%B0%E4%BC%A6%E8%B4%A5%E8%AF%89%E7%BD%91%E6%98%93&order=click"
},
{
"name": "宿傩死亡",
"url": "https://search.bilibili.com/all?vt=36849326&keyword=%E5%AE%BF%E5%82%A9%E6%AD%BB%E4%BA%A1&order=click"
},
{
"name": "黑神话Steam通关率不到14%",
"url": "https://search.bilibili.com/all?vt=36849326&keyword=%E9%BB%91%E7%A5%9E%E8%AF%9DSteam%E9%80%9A%E5%85%B3%E7%8E%87%E4%B8%8D%E5%88%B014%25&order=click"
}
]
},
"status": 200,
"statusText": "",
"headers": {
"content-type": "text/html; charset=UTF-8"
}
]

Axios.all()基于promise.all(),所有的都是成功的回调才会返回数据,如果有一个失败的回调,就会得到reject的状态,抛出Uncaught (in promise)错误。

出现Uncaught (in promise)的主要原因是Promise返回的reject状态没有被处理,系统自动抛出错误。解决方法可以参考上文响应拦截器的正文部分。