axios学习笔记(二)

响应结构

一个请求的响应包含以下信息。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
{
// `data` 由服务器提供的响应
data: {},

// `status` 来自服务器响应的 HTTP 状态码
status: 200,

// `statusText` 来自服务器响应的 HTTP 状态信息
statusText: 'OK',

// `headers` 是服务器响应头
// 所有的 header 名称都是小写,而且可以使用方括号语法访问
// 例如: `response.headers['content-type']`
headers: {},

// `config` 是 `axios` 请求的配置信息
config: {},

// `request` 是生成此响应的请求
// 在node.js中它是最后一个ClientRequest实例 (in redirects),
// 在浏览器中则是 XMLHttpRequest 实例
request: {}
}

当使用 then 时,您将接收如下响应:

1
2
3
4
5
6
7
axios.get("/user/12345").then(function (response) {
console.log(response.data);
console.log(response.status);
console.log(response.statusText);
console.log(response.headers);
console.log(response.config);
});

当使用 catch,或者传递一个rejection callback作为 then 的第二个参数时,响应可以通过 error 对象被使用,正如在错误处理部分解释的那样。

默认配置

您可以指定默认配置,它将作用于每个请求。

全局 axios 默认值

1
2
3
4
axios.defaults.baseURL = "https://api.example.com";
axios.defaults.headers.common["Authorization"] = AUTH_TOKEN;
axios.defaults.headers.post["Content-Type"] =
"application/x-www-form-urlencoded";

自定义实例默认值

1
2
3
4
5
6
7
// 创建实例时配置默认值
const instance = axios.create({
baseURL: "https://api.example.com",
});

// 创建实例后修改默认值
instance.defaults.headers.common["Authorization"] = AUTH_TOKEN;

配置的优先级

配置将会按优先级进行合并。它的顺序是:在 lib/defaults.js 中找到的库默认值,然后是实例的 defaults 属性,最后是请求的 config 参数。后面的优先级要高于前面的。下面有一个例子。

1
2
3
4
5
6
7
8
9
10
11
12
// 使用库提供的默认配置创建实例
// 此时超时配置的默认值是 `0`
const instance = axios.create();

// 重写库的超时默认值
// 现在,所有使用此实例的请求都将等待2.5秒,然后才会超时
instance.defaults.timeout = 2500;

// 重写此请求的超时时间,因为该请求需要很长时间
instance.get("/longRequest", {
timeout: 5000,
});

拦截器

20241106191355
在请求或响应被 then 或 catch 处理前拦截它们。

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
// 添加请求拦截器
axios.interceptors.request.use(
function (config) {
// 在发送请求之前做些什么
return config;
},
function (error) {
// 对请求错误做些什么
return Promise.reject(error);
}
);

// 添加响应拦截器
axios.interceptors.response.use(
function (response) {
// 2xx 范围内的状态码都会触发该函数。
// 对响应数据做点什么
return response;
},
function (error) {
// 超出 2xx 范围的状态码都会触发该函数。
// 对响应错误做点什么
return Promise.reject(error);
}
);

如果你稍后需要移除拦截器,可以这样:

1
2
3
4
const myInterceptor = axios.interceptors.request.use(function () {
/*...*/
});
axios.interceptors.request.eject(myInterceptor);

可以给自定义的 axios 实例添加拦截器。

1
2
3
4
const instance = axios.create();
instance.interceptors.request.use(function () {
/*...*/
});

错误处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
axios.get("/user/12345").catch(function (error) {
if (error.response) {
// 请求成功发出且服务器也响应了状态码,但状态代码超出了 2xx 的范围
console.log(error.response.data);
console.log(error.response.status);
console.log(error.response.headers);
} else if (error.request) {
// 请求已经成功发起,但没有收到响应
// `error.request` 在浏览器中是 XMLHttpRequest 的实例,
// 而在node.js中是 http.ClientRequest 的实例
console.log(error.request);
} else {
// 发送请求时出了点问题
console.log("Error", error.message);
}
console.log(error.config);
});

使用 validateStatus 配置选项,可以自定义抛出错误的 HTTP code。

1
2
3
4
5
axios.get("/user/12345", {
validateStatus: function (status) {
return status < 500; // 处理状态码小于500的情况
},
});

使用 toJSON 可以获取更多关于 HTTP 错误的信息。

1
2
3
axios.get("/user/12345").catch(function (error) {
console.log(error.toJSON());
});

取消请求

AbortController
从 v0.22.0 开始,Axios 支持以 fetch API 方式—— AbortController 取消请求:

1
2
3
4
5
6
7
8
9
10
11
const controller = new AbortController();

axios
.get("/foo/bar", {
signal: controller.signal,
})
.then(function (response) {
//...
});
// 取消请求
controller.abort();

. 如何取消未完成的请求?

  1. 当配置了 cancelToken 对象时, 保存 cancel 函数
    (1) 创建一个用于将来中断请求的 cancelPromise
    (2) 并定义了一个用于取消请求的 cancel 函数
    (3) 将 cancel 函数传递出来
  2. 调用 cancel()取消请求
    (1) 执行 cacel 函数, 传入错误信息 message
    (2) 内部会让 cancelPromise 变为成功, 且成功的值为一个 Cancel 对象
    (3) 在 cancelPromise 的成功回调中中断请求, 并让发请求的 proimse 失败,
    失败的 reason 为 Cancel 对象