Axios

Axios是干什么的

上古浏览器页面在向服务器请求数据时,因为返回的是整个页面的数据,页面都会强制刷新一下,这对于用户来讲并不是很友好。并且我们只是需要修改页面的部分数据,但是从服务器端发送的却是整个页面的数据,十分消耗网络资源。而我们只是需要修改页面的部分数据,也希望不刷新页面,因此异步网络请求就应运而生。

Ajax(Asynchronous JavaScript and XML):异步网络请求。Ajax能够让页面无刷新的请求数据。

实现ajax的方式有多种,如jQuery封装的ajax,原生的XMLHttpRequest,以及axios。但各种方式都有利弊

为什么需要Axios

  1. 原生的XMLHttpRequest的配置和调用方式都很繁琐,实现异步请求十分麻烦

    原生XMLHttpRequest实现ajax请求如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    var request = new XMLHttpRequest(); // 创建XMLHttpRequest对象
    //ajax是异步的,设置回调函数
    request.onreadystatechange = function () { // 状态发生变化时,函数被回调
    if (request.readyState === 4) { // 成功完成
    // 判断响应状态码
    if (request.status === 200) {
    // 成功,通过responseText拿到响应的文本:
    return success(request.responseText);
    } else {
    // 失败,根据响应码判断失败原因:
    return fail(request.status);
    }
    } else {
    // HTTP请求还在继续...
    }
    }
    // 发送请求:
    request.open('GET', '/api/categories');
    request.setRequestHeader("Content-Type", "application/json") //设置请求头
    request.send();//到这一步,请求才正式发出

  2. jQuery的ajax相对于原生的ajax是非常好用的,但是没有必要因为要用ajax异步网络请求而引用jQuery框架

  3. Axios,本质上还是对原生XMLHttpRequest的封装,可用于浏览器和nodejs的HTTP客户端,只不过它是基于Promise的,符合最新的ES规范。

Axios的特点

  1. 在浏览器中创建XMLHttpRequest请求
  2. 在node.js中发送http请求
  3. 支持Promise API
  4. 拦截请求和响应
  5. 转换请求和响应数据
  6. 取消要求
  7. 自动转换JSON数据
  8. 客户端支持防止CSRF/XSRF(跨域请求伪造)

使用方法

官网下载,说明文档:https://axios-http.com/zh/
引入CDN: https://cdn.bootcdn.net/ajax/libs/axios/0.21.1/axios.min.js

axios请求案例

1
2
3
4
5
6
 <script src=" https://cdn.bootcdn.net/ajax/libs/axios/0.21.1/axios.min.js"></script>
<script>
axios.get('https://study.duyiedu.com/api/herolist').then((resp)=>{
console.log(resp.data);//resp.data为响应体的数据,axios会自动解析JS0N格式
})
</script>

resp.data为响应体的数据,axios会自动解析JS0N格式

1
2
3
4
(async function ()
const resp await axios.get('https://study.duyiedu.com/api/herolist');
console.log(resp.data);
})();

由于axios.get返回的是一个promise,所以用async和await也可以实现

1
2
3
4
5
6
7
8
9
10
11
12
<script>
axios
.get("https://study.duyiedu.com/api/user/exists", {
params: {
//这里可以配置query(参数),axios:会自动将其进行Url编码
loginId: "abc",
},
})
.then((resp) => {
console.log(resp.data);
});
</script>

axios可以配置query(参数),axios:会自动将其进行Url编码

1
2
3
4
5
6
7
8
9
10
<script>
axios
.post("https://study.duyiedu.com/api/user/reg", {
loginId: "abc",
loginPwd: "123123",
nickname: "棒棒鸡",
}).then((resp) => {
console.log(resp.data); //resp.data为响应体的数据,axios会自动解析JS0N格式
});
</script>

还会将响应头中的Content-Type自动转化为application/json

image-20231130195907113

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//执行GET请求
import axios from 'axios'
axios.default.baseURL = 'http://localhost:3000/api/products'
axios.get('/user?ID=12345') //返回的是一个Promise
.then(res=>console.log(res))
.catch(err=>console.log(err));

//可配置参数的方式
axios.get('/user',{
params:{
ID:12345
}
}).then(res=>console.log(res))
.catch(err=>console.log(err));

1
2
3
4
5
6
7
8
//发送post请求
axios.post('/user',{
firstName: 'simon',
lastName:'li'
}).then(res=>console.log(res))
.catch(err=>console.log(err));


Axios的请求方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
1.axios.get(urL地址,[请求配置]);

2.axios.post(urL地址,[请求体对象],[请求配置]);

3.axios(请求配置);//或直接使用axios方法,在请求配置中填写请求方法

4.axios.request(config)

5.axios.put(url [,data [,config]])

6.axios.delete(url [,config])

7.axios.patch(url [,data [,config]])

8.axios.head(url [,config])

注意: []里的内容表示可以忽略不写

Axios发送并发请求

通过axios.all(iterable)可实现发送多个请求,参数不一定是数组,只要有iterable接口就行,函数返回的是一个数组

axios.spread(callback)可用于

1
2
3
4
5
6
7
8
9
//发送多个请求(并发请求),类似于promise.all,若一个请求出错,那就会停止请求
const get1 = axios.get('/user/12345');
const get2 = axios.get('/user/12345/permission');
axios.all([get1,get2]) //发送多个请求
.then(axios.spread((res1,res2)=>{ //将结果数组展开
console.log(res1,res2);
}))
.catch(err=>console.log(err))

请求中config中的默认设置

示例:

1
2
3
4
5
6
7
8
9
10
11
const instance = axios.create({
baseURL: 'http://localhost:3000/api/products',
timeout: 1000,
headers: {'X-Custom-Header':'foobar'}
});
//instance的使用
instance.get('/user',{
params:{ID:12345} //请求中config中的默认设置
}).then(res=>console.log(res))
.catch(err=>console.log(err))

创建一个Axios实例(或称实例默认设置)

axios允许开发者先创建一个实例,后续通过使用实例进行请求,这样做的好处是可以预先进行某些配置

1
2
3
4
5
6
7
8
9
//创建实例
const instance = axios.create({
baseURL: 'https://study.duyiedu.com/'
});

//发送get请求到https://study.duyiedu.com/api/herolist,输出响应体的内容
instance.get("/api/herolist").then(resp=>{
console.Log(resp.data);//resp.data为响应体的数据,axios会自动解析JS0N格式
})

全局默认设置

全局默认设置是指给axios添加一些默认设置,如baseURL等,后面发送请求时,所有请求都会带上这些设置

1
2
3
import axios from 'axios'
axios.default.baseURL = 'http://localhost/api/';
axios.default.headers.common['Authorization'] = AUTH_TOKEN;

设置优先级

设置是可以被覆盖的,设置包括了全局默认设置,实例默认设置以及请求中config中的默认设置,越往后,优先级越高,后面的会覆盖前面的设置

拦截器

概念:

拦截器是指当发送请求或者得到响应被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

//添加请求拦截器
axios.interceptors.request.use(function (config){
//config为当前的请求配置
//use表示在发送请求之前做些什么
//这里,我们添加一个请求头
const token = localStorage.getItem('token');//token是授权码
if(token){
config.headers.authorization=token;
}
return config;//返回处理后的配置
});


//添加响应拦截器
axios.interceptors.response.use(function (resp){
//2x×范围内的状态码都会触发该函数。
//对响应数据做点什么
return resp.data.data;//仅得到响应体中的data属性
},function (error){
//超出2×范围的状态码都会触发该函数。
//对响应错误做点什么
alert(error.message);//弹出错误消息
)
1
2
3
4
5
6
7
8
9

//移除拦截器
const myInterceptor = axios.interceptors.request.use(config=>{return cofig})
axios.interceptors.request.eject(myInterceptor);

//在一个axios实例中使用拦截器
var instance = axios.create();
instance.interceptors.request.use(function(){/*...*/});

取消请求

可以使用cancel token取消一个请求,当用户搜索时,可能需要频繁的发送数据查询请求,因此当发送下一个请求时 ,需要撤销上一个请求。因此需要取消请求。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

const CancelToken = axios.CancelToken;
//使用CancelToken.source工厂函数创建一个cancel token
const source = CancelToken.source();

axios.get('/user/12345',{
cancelToken: source.token
}).catch(thrown=>{
if(axios.isCancel(thrown)){
console.log('Request canceled', thrown.message);
}else{
//handle error
}
});

//取消请求
source.cancel('操作被用户取消');