⭐️⭐️⭐️ 作者:船长在船上
axios从入门到源码分析
第1章:axios的理解和使用
1.1.axios是什么?
- 前端最流行的ajax请求库
- react/vue官方都推荐使用axios发ajax请求
- 文档: https://github.com/axios/axios
1.2.axios特点
- 基于 xhr + promise 的异步 ajax 请求库
- 浏览器端/node 端都可以使用
- 支持请求/响应拦截器
- 支持请求取消
- 请求/响应数据转换
- 批量发送多个请求
1.3. axios 常用语法
- axios(config): 通用/最本质的发任意类型请求的方式
- axios(url[, config]): 可以只指定 url 发 get 请求
- axios.request(config): 等同于 axios(config)
- axios.get(url[, config]): 发 get 请求
- axios.delete(url[, config]): 发 delete 请求
- axios.post(url[, data, config]): 发 post 请求
- axios.put(url[, data, config]): 发 put 请求
- axios.defaults.xxx: 请求的默认全局配置
- axios.interceptors.request.use(): 添加请求拦截器
- axios.interceptors.response.use(): 添加响应拦截器
- axios.create([config]): 创建一个新的 axios(它没有下面的功能)
- axios.Cancel(): 用于创建取消请求的错误对象
- axios.CancelToken(): 用于创建取消请求的 token 对象
- axios.isCancel(): 是否是一个取消请求的错误
- axios.all(promises): 用于批量执行多个异步请求
- axios.spread(): 用来指定接收所有成功数据的回调函数的方法
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>axios基本使用</title>
<link crossorigin="anonymous" href="https://cdn.bootcss.com/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.1/axios.min.js"></script>
</head>
<body>
<div class="container">
<h2 class="page-header">基本使用</h2>
<button class="btn btn-primary"> 发送GET请求 </button>
<button class="btn btn-warning" > 发送POST请求 </button>
<button class="btn btn-success"> 发送 PUT 请求 </button>
<button class="btn btn-danger"> 发送 DELETE 请求 </button>
</div>
<script>
//获取按钮
const btns = document.querySelectorAll('button');
//第一个
btns[0].onclick = function(){
//发送 AJAX 请求
axios({
//请求类型
method: 'GET',
//URL
url: 'http://localhost:3000/posts/2',
}).then(response => {
console.log(response);
});
}
//添加一篇新的文章
btns[1].onclick = function(){
//发送 AJAX 请求
axios({
//请求类型
method: 'POST',
//URL
url: 'http://localhost:3000/posts',
//设置请求体
data: {
title: "今天天气不错, 还挺风和日丽的",
author: "张三"
}
}).then(response => {
console.log(response);
});
}
//更新数据
btns[2].onclick = function(){
//发送 AJAX 请求
axios({
//请求类型
method: 'PUT',
//URL
url: 'http://localhost:3000/posts/3',
//设置请求体
data: {
title: "今天天气不错, 还挺风和日丽的",
author: "李四"
}
}).then(response => {
console.log(response);
});
}
//删除数据
btns[3].onclick = function(){
//发送 AJAX 请求
axios({
//请求类型
method: 'delete',
//URL
url: 'http://localhost:3000/posts/3',
}).then(response => {
console.log(response);
});
}
</script>
</body>
</html>
1.4. 难点语法的理解和使用
1.4.1. axios.create(config)
1.根据指定配置创建一个新的 axios, 也就就每个新 axios 都有自己的配置
2.新 axios 只是没有取消请求和批量发请求的方法, 其它所有语法都是一致的
3.为什么要设计这个语法?
(1) 需求 : 项目中有部分接口需要的配置与另一部分接口需要的配置不太一
样 , 如何处理
(2) 解决 : 创建 2 个新 axios, 每个都有自己特有的配置 , 分别应用到不同要
求的接口请求中
拦截器函数/ajax 请求/请求的回调函数的调用顺序
1. 说明: 调用 axios()并不是立即发送 ajax 请求, 而是需要经历一个较长的流程
2. 流程: 请求拦截器2 => 请求拦截器1 => 发ajax请求 => 响应拦截器1 => 响
应拦截器 2 => 请求的回调
3. 注意: 此流程是通过 promise 串连起来的, 请求拦截器传递的是 config, 响应
拦截器传递的是 response
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>拦截器</title>
<script src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.1/axios.min.js"></script>
</head>
<body>
<script>
// Promise
// 设置请求拦截器 config 配置对象
axios.interceptors.request.use(function (config) {
console.log('请求拦截器 成功 - 1号');
//修改 config 中的参数
config.params = {a:100};
return config;
}, function (error) {
console.log('请求拦截器 失败 - 1号');
return Promise.reject(error);
});
axios.interceptors.request.use(function (config) {
console.log('请求拦截器 成功 - 2号');
//修改 config 中的参数
config.timeout = 2000;
return config;
}, function (error) {
console.log('请求拦截器 失败 - 2号');
return Promise.reject(error);
});
// 设置响应拦截器
axios.interceptors.response.use(function (response) {
console.log('响应拦截器 成功 1号');
return response.data;
// return response;
}, function (error) {
console.log('响应拦截器 失败 1号')
return Promise.reject(error);
});
axios.interceptors.response.use(function (response) {
console.log('响应拦截器 成功 2号')
return response;
}, function (error) {
console.log('响应拦截器 失败 2号')
return Promise.reject(error);
});
//发送请求
axios({
method: 'GET',
url: 'http://localhost:3000/posts'
}).then(response => {
console.log('自定义回调处理成功的结果');
console.log(response);
});
</script>
</body>
</html>
1.4.2. 取消请求
1. 基本流程
- 配置 cancelToken 对象
- 缓存用于取消请求的 cancel 函数
- 在后面特定时机调用 cancel 函数取消请求
- 在错误回调中判断如果 error 是 cancel, 做相应处理
2. 实现功能
- 点击按钮, 取消某个正在请求中的请求
- 在请求一个接口前, 取消前面一个未完成的请求
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>取消请求</title>
<link crossorigin='anonymous' href="https://cdn.bootcss.com/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.1/axios.min.js"></script>
</head>
<body>
<div class="container">
<h2 class="page-header">axios取消请求</h2>
<button class="btn btn-primary"> 发送请求 </button>
<button class="btn btn-warning" > 取消请求 </button>
</div>
<script>
//获取按钮
const btns = document.querySelectorAll('button');
//2.声明全局变量
let cancel = null;
//发送请求
btns[0].onclick = function(){
//检测上一次的请求是否已经完成
if(cancel !== null){
//取消上一次的请求
cancel();
}
axios({
method: 'GET',
url: 'http://localhost:3000/posts',
//1. 添加配置对象的属性
cancelToken: new axios.CancelToken(function(c){
//3. 将 c 的值赋值给 cancel
cancel = c;
})
}).then(response => {
console.log(response);
//将 cancel 的值初始化
cancel = null;
})
}
//绑定第二个事件取消请求
btns[1].onclick = function(){
cancel();
}
</script>
</body>
</html>