第八篇:基于Promise的axios
【axios是什么】
Axios,是一个基于promise [5] 的网络请求库,作用于node.js和浏览器中,它是 isomorphic 的(即同一套代码可以运行在浏览器和node.js中)。在服务端它使用原生node.js http模块, 而在客户端 (浏览端) 则使用XMLHttpRequest
GitHub 下载地址
文档 中文文档
1.准备一个较完整的后端接口 服务器 提取码(l14u) 下载地址
2.测试服务器的接口有无异常
工具 Postman 下载地址
-----------------------------------------------准备测试页面---------------------------------------------------------------
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h3>axios前后端常用接口文档测试</h3>
<p>[---axios接口测试---]</p>
<button id="btn01" type="button">点击获取所有人信息</button><br><br>
<button id="btn02" type="button">点击获取某人信息</button>
<input type="text" id="person_id" placeholder="请输入个人id"><br><br>
<button id="btn03">点击添加一个人的信息</button>
<input type="text" id="personName" placeholder="请输入姓名">
<input type="text" id="personAge" placeholder="请输入年龄"><br><br>
<button id="btn04">点击更新一个人的信息</button>
<input type="text" id="update_id" placeholder="请输入要更新的id">
<input type="text" id="update_name" placeholder="请输入要更新的姓名">
<input type="text" id="update_age" placeholder="请输入要更新的年龄"><br><br>
<button id="btn05" type="button">点击删除某人信息</button>
<input type="text" id="delete_id" placeholder="请输入要删除的id">
</body>
</html>
//引入axios
<script type="text/javascript" src="./js/axios.min.js"></script>
<script>
// 获取按钮信息
let btn01 = document.getElementById('btn01');
let btn02 = document.getElementById('btn02');
let btn03 = document.getElementById('btn03');
let btn04 = document.getElementById('btn04');
let btn05 = document.getElementById('btn05');
// 获取输入信息
let personId = document.getElementById('person_id');
let personName = document.getElementById('personName');
let personAge = document.getElementById('personAge');
let updateId = document.getElementById('update_id');
let updateName = document.getElementById('update_name');
let updateAge = document.getElementById('update_age');
let deleteId = document.getElementById('delete_id');
HTML页面
【语法】
GET方法不携带参数 --------查询搜有人信息
//(1)GET不携带参数完整版)查询搜有人信息
btn01.onclick = ()=>{
axios({
url:'http://localhost:5000/persons',
method:'GET',
})
.then(
response =>{
console.log('成功了',response.data);
},
error =>{
console.log('失败了',error);
}
)
}
//(2)GET不携带参数精简版)查询搜有人信息
btn01.onclick = ()=>{
axios.get('http://localhost:5000/persons').then(
response=>{console.log('请求成功了',response.data);},
error=>{console.log(error);}
)
}
GET方法携带query参数-------查询某个人的信息
//GET携带query参数完整版】查询某个人的信息
btn02.onclick = ()=>{
axios({
url:'http://localhost:5000/person',
method:'GET',
params:{id:personId.value}
})
.then(
response =>{console.log('成功了',response.data);},
error =>{console.log('失败了',error);}
)
}
//GET携带query参数精简版】查询某个人的信息
btn02.onclick = ()=>{
axios.get('http://localhost:5000/person',{params:{id:personId.value}}).then(
response =>{console.log('成功了',response.data);},
error =>{console.log('失败了',error);}
)
}
对于GET方法携带params参数来说是直接拼接在url中
`http://localhost:5000/person/${personId.value}`
POST方法携带请求体参数----------添加某个人的信息
//POST携带请求体参数完整版】添加某个人的信息
btn03.onclick = ()=>{
axios({
url:'http://localhost:5000/person',
method:'POST',
// data:{name:personName.value,age:personAge.value}//json格式
data:`name=${personName.value}&age=${personAge.value}`//urlencoded格式
})
.then(
response =>{console.log('成功了',response.data);},
error =>{console.log('失败了',error);}
)
}
//【精简版】添加某个人的信息
btn03.onclick = ()=>{
axios.post('http://localhost:5000/person',{name:personName.value,age:personAge.value}).then(
response =>{console.log('添加加成功了',response.data);},
error =>{console.log('失败了',error);}
)
}
PUT方法携带请求体参数---------更新某个人的信息
//PUT携带参数完整版】更新某个人的信息
btn04.onclick = ()=>{
axios({
url:'http://localhost:5000/person',
method:'PUT',
data:{
id:updateId.value,
name:updateName.value,
age:updateAge.value,}
})
.then(
response =>{console.log('添加加成功了',response.data);},
error =>{console.log('失败了',error);}
)
}
// 【精简版】
btn04.onclick = ()=>{
axios.put('http://localhost:5000/person',
{
id:updateId.value,
name:updateName.value,
age:updateAge.value
}).then(
response =>{console.log('添加加成功了',response.data);},
error =>{console.log('失败了',error);}
)
}
DELETE携带params参数--------删除某个人的信息 携带params参数 手动拼接
//DELETE携带参数完整版】删除某个人的信息 携带params参数 手动拼接
btn05.onclick = ()=>{
axios({
url:`http://localhost:5000/person/${deleteId.value}`,
method:'DELETE'
}).then(
response =>{console.log('添加加成功了',response.data);},
error =>{console.log('失败了',error);}
)
}
//DELETE携带参数精简版】删除某个人的信息 携带params参数 手动拼接
btn05.onclick = ()=>{
axios.delete(`http://localhost:5000/person/${deleteId.value}`).then(
response =>{console.log('删除成功了',response.data);},
error =>{console.log('失败了',error);}
)
}
【axios的常用配置项介绍 】
// 给axios配置默认属性
axios.defaults.timeout = 2000;//配置默认超时时间
axios.defaults.headers = {school:'wuhan'};//配置默认请求头
axios.defaults.baseURL = 'http://localhost:5000';//配置默认主机端口
btn.onclick = ()=>{
axios({
url:'/test1',//请求地址
method:'GET',//请求方式
// params:{delay:3000},//配置query参数
// data:{c:3,d:4},//配置请求体为json参数
// data:`e=5&f=7`,//配置请求体为urlencoded参数
// timeout:2000,//配置超时时间
// headers:{demo:123}
// responseType:'json'//默认设置响应数据的格式
}).then(
response =>{console.log('成功了',response.data);},
error=>{console.log('失败了',error.message);}
)
}
使用axios.create方法 创建一个新的axios
为什么要设计这个语法?
需求:项目中有部分接口需要的配置与另一部分接口需要的配置不太一样
根据指定配置创建一个新的axios,也就是每个新的axios都有自己的配置
新axios只是没有取消请求和批量发请求的方法,其他所有语法都是一致的
// 给默认axios配置默认属性
axios.defaults.timeout = 2000;
axios.defaults.headers = {school:'wuhan'};
axios.defaults.baseURL = 'http://localhost:5000';
//使用默认axios
btn.onclick = ()=>{
axios({
url:'/test1',//请求地址
method:'GET',//请求方式
// params:{delay:3000},//配置query参数
// data:{c:3,d:4},//配置请求体为json参数
// data:`e=5&f=7`,//配置请求体为urlencoded参数
// timeout:2000,//配置超时时间
// headers:{demo:123}
// responseType:'json'//默认设置响应数据的格式
}).then(
response =>{console.log('成功了',response.data);},
error=>{console.log('失败了',error.message);}
)
}
//若需要使用新的axios且需要给其配置默认属性
const axios2 = axios.create({
timeout:3000,
headers:{school:'wuhan'},
baseURL:'http://localhost:3000'//给另一台服务器发送请求
});
【axios的拦截器】
------------什么是请求拦截器?
axios.interceptors.request.use((config)=>{})
1.是什么 在真正发送请求执行前的一个回调函数
2.作用:对所有的请求做统一的处理: 追加请求头、追加参数、界面loading提示等等
应用场景以及使用方法
现在想每次发送请求的时候判断当前时间戳是否为奇偶数若为奇数就给请求头添加一个属性 school 值是 @wuhan
const btn = document.getElementById('btn01');
// 给axios配置默认属性
axios.defaults.baseURL = 'http://localhost:5000';
axios.defaults.timeout = 2000;
axios.defaults.responseType = 'json';
// 请求拦截器的配置
axios.interceptors.request.use((config)=>{
//confi是一个大的对象包括请求的数据
//在请求拦截其中可以操作该对象
//判断时间戳并操作config
if(Date.now()%2===0){
config.headers.school = '@wuhan'
}
//尝试给config添加一个a属性 值为1
config.a = 1;
console.log(config);
//记得操作完之后 一定要返回该对象 不然请求的数据会被清空
return config;
});
//不带参数发送一个简单的请求
btn.onclick = ()=>{
axios.get('persons',{data:{}}).then(
response =>{console.log('成功了',response.data);},
error =>{console.log('失败了',error);}
)
};
响应拦截器
axios.interceptors.response.use(
response=>{ },
error=>{}
)
1.是什么 得到响应之后执行的一个回调函数
2.作用:若请求成功 对成功的数据进行处理
若请求失败,对失败进异步操作
应用场景及使用方法
场景:当前时间戳为偶数时可以返回数据 若为奇数时则返回 一个字符串 "时间不吻合不能返回数据"
axios.interceptors.response.use(
response=>{
console.log('响应拦截器成功的回调执行了');
if(Date.now()%2===0){
return response.data;
}else{
return '时间不吻合不能返回数据'
}
},
error=>{
alert(error.message);
return new Promise(()=>{});
//失败返回一个pending的Promise实例 这个很关键 因为只有返回一个状态为pending
//的promise实例直接结束 不用进入下一个判断
}
)
第一种情况当响应成功 单时间戳不符合 就返回 时间不吻合不能返回数据
第二种情况响应成功了且时间戳也对 返回正确的数据
第三种响应错误了
【 axios取消请求的方法】CancelToken
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>axios取消请求</title>
</head>
<body>
<h3>axios取消请求</h3>
<p>[-----取消请求----]</p>
<button id="btn01">点击请求</button>
<button id="btn02">点击取消请求</button>
<script src="./js/axios.min.js"></script>
<script>
const btn01 = document.getElementById('btn01');
const btn02 = document.getElementById('btn02');
//取出CancelToken这个对象
const {CancelToken} = axios;//获取CancelToken能为每一次请求打标机
//定义一个全局变量用来接收取消请求的函数对象 c
let cancel;
btn01.onclick = () => {
axios({
url: 'http://localhost:5000/test1',
method: 'GET',
params:{delay:3000},//添加一个延迟的时间 以便于取消操作
//给当前请求添加Token标记 并传递取消当前请求c函数
cancelToken:new CancelToken(c=>{
// console.log(c);//c是一个函数,调用c就可以关闭本次请求
// c();直接取消请求 根本发不出去
cancel = c;//将cancel指向和c一样
})
}).then(
response => { console.log('成功了', response.data); },
error => { console.log('失败了', error.message); }
)
}
btn02.onclick = () => {
//点击取消请求的时候 调用取消函数
cancel();
}
</script>
</body>
</html>
【避免一个按钮多次重复请求】配合拦截器一起使用
请求拦截器 取消请求
响应拦截器 处理 响应错误的两种方式(用户取消 一般的响应错误)
<script src="./js/axios.min.js"></script>
<script>
const btn01 = document.getElementById('btn01');
//取出 CancelToken 和 isCancel 对象
const {CancelToken,isCancel} = axios;//获取CancelToken能为每一次请求打标记
let cancel;
// 请求拦截器
axios.interceptors.request.use((config)=>{
// console.log('请求拦截器启动了');
// 设置请求配置条件
//判断 当点击按钮时 cancel值为真的时候 表示可以使用取消请求函数
if(cancel){
cancel();
}
发送请求的时候添加 CancelToken的实力 并传递取消请求的对象 c
config.cancelToken = new CancelToken((c)=>{cancel=c});
return config
});
// 响应拦截器
axios.interceptors.response.use(
response=>{
// console.log('响应拦截器启动了');
return response.data; //响应成功的返回值
},
error =>{
//响应错误的时候有两种情况
// 一、当是用户取消请求的时候
if(isCancel(error)){
console.log('用户取消了请求');
return new Promise(()=>{});//响应失败的返回值
}else{//不是用户取消请求而发生错误的时候
alert(error.message);
return new Promise(()=>{});//响应失败的返回值
}
}
)
//使用async...await只接受成功的数据 因为响应拦截器已经为错误做了处理
btn01.onclick = async()=>{
const res = await axios.get('http://localhost:5000/test1?delay=3000');
console.log(res);
}
【axios批量发送请求的方法】axios.all([]).then()
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>批量发送请求</title>
</head>
<body>
<h3>批量发送请求</h3>
<p>[---批量请求---]</p>
<button id="btn01">点我同时发送三个请求</button>
<script src="./js/axios.min.js"></script>
<script>
const btn01 = document.getElementById('btn01');
btn01.onclick = () => {
axios.all([
axios.get('http://localhost:5000/test1'),
axios.get('http://localhost:5000/test2?delay=3000'),
axios.get('http://localhost:5000/test3')
])
.then(
response => { console.log('成功了', response); },
error => { console.log('失败了'); }
)
}
</script>
</body>
</html>