Axios总结(个人留存)
一、API的分类
注意:API和URL表示定位资源,请求的METHOD表示对这个资源进行的操作方式
1.1 REST(restful)API:符合rest架构风格的网络API接口
1. 发送请求进行CRUD【增删改查】哪一个操作,由请求方式来决定
2. 同一个请求路径可以进行多个操作(表示同一个地址,可以多种请求方式,但代表的操作不同)
3. 请求方式会用到GET/POST/PUT/DELETE
获取(get):从服务器端读取数据
删除(delete):删除服务端数据
更新(put):更新服务端已存在的数据(替换)
添加(post):向服务器端添加新数据
1.2 非REST(restless) API:除去rest风格以外的API
1. 请求方式不取决于请求的CRUD【增删改查】操作
2. 一个请求路径只能对应一个操作
3. 一般请求方式只有GET/POST
获取(get):http://127.0.0.1/getInfo
删除(get):http://127.0.0.1/delInfo
更新(post):http://127.0.0.1/upInfo
添加(post):http://127.0.0.1/addInfo
二、使用json-server搭建restful API
2.1 json-server的作用
用来快速搭建模拟的REST API的工具包
- 搭建站点服务
- 提供数据的实现模拟相关操作
1.在线文档:json-server在线文档
2.文档内容分析博客:跃哥分享
2.2 使用json-server:提供数据的模拟响应
- 首先要安装Node
由于json-server需要通过Node对其进行启动,所以要先安装Node- 全局安装json-server
npm install json-server -g- 查看版本
json-server -v- 准备一份JSON文件:必须是一个对象,不能是数组
- 启动的相关命令
--watch:可以省略,如果省略,数据发生改变不会及时响应。
--delay:指定延长响应的时间,单位为毫秒。
--port:指定端口号。
host:主机名。
//终端内执行
//要在进入目录后(不可直接再cd /路径后面直接运行),再运行指令,否则报错
//指令代表:运行json-server搭建服务,--watch实时响应(在数据发生改变后),可以写在json文件的前面,也可以写在后面,--port将端口号设置为80,--host设置主机名(127.0.0.1),--delay设置服务响应的延时时间(单位毫秒:ms)
json-server --watch index.json --port 80 --host zhangpeiyue.com --delay 2000
//JSON模拟数据文件
{
"scoreList":[
{
"id":1,
"userName":"张三",
"age":12,"sex":"男",
"score":{"yuWen":10,"shuXue":20,"yingYu":30}
},
{
"id":2,
"userName":"李四",
"age":21,
"sex":"女",
"score":{"yuWen":12,"shuXue":45,"yingYu":37}
},
{
"id":3,
"userName":"王五",
"age":56,
"sex":"男",
"score":{"yuWen":12,"shuXue":20,"yingYu":30}
},
{
"id":4,
"userName":"赵六",
"age":23,
"sex":"女",
"score":{"yuWen":19,"shuXue":21,"yingYu":65}
},
{
"id":5,
"userName":"严七",
"age":12,
"sex":"男",
"score":{"yuWen":34,"shuXue":67,"yingYu":43}
},
{
"id":6,
"userName":"沈八",
"age":43,
"sex":"女",
"score":{"yuWen":56,"shuXue":76,"yingYu":30}
},
{
"id":7,
"userName":"钱九",
"age":13,
"sex":"男",
"score":{"yuWen":24,"shuXue":89,"yingYu":30}
},
{
"id":8,
"userName":"张十",
"age":12,
"sex":"女",
"score":{"yuWen":10,"shuXue":54,"yingYu":31}
}
]
}
2.3 使用浏览器访问测试
http://127.0.0.1/scoreList //获取所有数据
http://127.0.0.1/scoreList/1 //查找ID为1的数据,找不到数据响应结果为{}空对象
http://127.0.0.1/scoreList?age=12&sex=男 //查找数据种,所有性别为男,且年龄为12的数据列表
三、 fetch
3.1 区分一般的http请求与ajax请求
- ajax请求是一种特别的http请求。
- 对服务器端来说,没有任何区别,区别再浏览器端。
- 浏览器端发请求:
只有XHR或fetch发出的才是ajax请求,其它的所有的请求都是非ajax请求。- 浏览器端接收到响应
(1)一般请求:浏览器一般会直接显示响应体数据,也就是我们常说的刷新或跳转页面。
(2)ajax请求:浏览器不会对界面进行任何更新操作,只是调用监视的回调函数,并传入响应的相关数据。
3.2 fetch的使用
3.2.1 代码展示说明
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<button>get</button>
<button>post</button>
<button>put</button>
<button>patch</button>
<button>delete</button>
</body>
<script type="module">
const btns = document.querySelectorAll("button");
// import ajax from "./index.js";
btns[0].onclick = async function () {
// 1- fetch是window对象下的方法
console.log(window.fetch)
// 2- fetch返回的是一个Promise实例
// 发送一个GET请求,并将结果赋值给result
const result = fetch("http://zhangpeiyue.com/scoreList?age=12");
console.log(result);
// 3- 获取响应体数据
// 3-1- 非链式调用
const result = fetch("http://zhangpeiyue.com/scoreList?age=12");
const res = result.then(value=>{
console.log(value.json());
console.log(value.text());
// return value.json();
return value.text();
})
res.then(value=>{
console.log(value);
})
// 3-2-链式调用
fetch("http://zhangpeiyue.com/scoreList?age=12").then(value => {
return value.json();// 将响应体的数据转为JSON对象,并作为返回Promise的成功值
}).then(value => {
console.log(value);// 转为JSON对象以后的响应体数据
})
// 3-3- async await
const result = await fetch("http://zhangpeiyue.com/scoreList?age=12");
const body = await result.json();
console.log(body);
// 3-4- 简单封装一下
const {default:ajax} = await import("./index.js");
ajax("http://zhangpeiyue.com/scoreList",{
params:{
age:12,
sex:"女"
}
}).then(value=>{
console.log(value);
})
}
btns[1].onclick = function(){
// fetch是一个方法,第一个参数是请求地址,第二个参数是配置对象
// x-www-form-urlencoded
fetch("http://zhangpeiyue.com/scoreList",{
method:"post",// 请求方式
headers:{// 请求头
"Content-Type":"application/x-www-form-urlencoded"
},
body:"userName=老郭头&age=90"
}).then(value=>{
value.json().then(value=>{
console.log(value);// 响应体数据
})
})
// json
fetch("http://zhangpeiyue.com/scoreList",{
method:"post",// 请求方式
headers:{// 请求头
"Content-Type":"application/json"
},
body:JSON.stringify({
userName:"老王头",
age:80
})
}).then(value=>{
value.json().then(value=>{
console.log(value);// 响应体数据
})
})
}
btns[2].onclick = function(){
// fetch是一个方法,第一个参数是请求地址,第二个参数是配置对象
// x-www-form-urlencoded
// fetch("http://zhangpeiyue.com/scoreList/1",{
// method:"put",// 请求方式
// headers:{// 请求头
// "Content-Type":"application/x-www-form-urlencoded"
// },
// body:"userName=老郭头&age=90"
// }).then(value=>{
// value.json().then(value=>{
// console.log(value);// 响应体数据
// })
// })
// json
fetch("http://zhangpeiyue.com/scoreList/2",{
method:"put",// 请求方式
headers:{// 请求头
"Content-Type":"application/json"
},
body:JSON.stringify({
userName:"老王头",
age:80
})
}).then(value=>{
value.json().then(value=>{
console.log(value);// 响应体数据
})
})
}
btns[3].onclick = function(){
// fetch是一个方法,第一个参数是请求地址,第二个参数是配置对象
// x-www-form-urlencoded
fetch("http://zhangpeiyue.com/scoreList/3",{
method:"PATCH",// 请求方式
headers:{// 请求头
"Content-Type":"application/x-www-form-urlencoded"
},
body:"userName=老郭头&age=90"
}).then(value=>{
value.json().then(value=>{
console.log(value);// 响应体数据
})
})
// json
fetch("http://zhangpeiyue.com/scoreList/4",{
method:"PATCH",// 请求方式
headers:{// 请求头
"Content-Type":"application/json"
},
body:JSON.stringify({
userName:"老王头",
age:80
})
}).then(value=>{
value.json().then(value=>{
console.log(value);// 响应体数据
})
})
}
btns[4].onclick = function(){
fetch("http://zhangpeiyue.com/scoreList/3",{
method:"delete",// 请求方式
}).then(value=>{
value.json().then(value=>{
console.log(value);// 响应体数据
})
})
}
{
// 练习
async function fn(){
await 100;
return new Promise(resolve=>{
setTimeout(()=>{
resolve(200)
})
});
}
console.log(fn());
}
</script>
</html>
3.2.2 fetch的特点
- fetch是windows对象下的方法
- fetch返回的是一个Promise实例
- fetch接收两个参数:①请求地址url;②配置对象config
3.2.3 fetch的相关使用说明(response.json())
fetch("http://zhangpeiyue.com/scoreList?age=12").then(value=>{
value.json().then(value=>{
console.log(value);// 响应体的数据
})
})
代码说明:
- 通过fetch请求数据>>>获得是一个成功的Promise实例,值为一个Response对象
- 然后通过then方法,获取到成功值Response
- 使用Response原型链上的json方法,获取到响应体数据
四、axios的理解和使用(重点)
4.1 axios是什么?
- 前端最流行的ajax请求库,没有之一
- react/vue官方都推荐使用axios发ajax请求
- 文档:axios在线文档
4.2 axios的特点
- 基于
xhr+promise的ajax请求库- 浏览器端和node端都可以使用
- 支持请求和响应拦截器(
重点)- 支持请求取消
- 支持批量发送多个请求
4.3 axios常用语法
- 引入axios.js
cnpm install axios -S //-S相当于--save 开发中的框架
- 再html中引入
<script src="../node_modules/axios/dist/axios.js"></script>
4.4 axios的基本使用
axios(config):通用,发任意类型请求的方式。默认为get方式,其他方式需要写配置项config//发送一个`POST`请求 axios({ method:"post", url:'http://127.0.0.1/scoreList', data:{ sex:"男", age: 12 } }); //发送一个`PUT`请求 axios({ // 请求方式 method:"put", // 请求地址 url:"http://127.0.0.1/scoreList/2", // 查询字符串 params:{ a:1, b:2 }, // 请求头 headers:{ userName:"lisi" }, // 请求体:application/x-www-form-urlencoded data:"userName=老刘头&age=61" // 请求体:application/json data:{ userName:"老汪头", age:66 } }).then(value=>{ console.log(value); })
axios(url,[config]):第一个参数是地址,第二个参数是配置项// 3- axios通过第二个参数配置项携带参数 axios("http://127.0.0.1/scoreList",{ params:{ age:12, sex:"男" } });
- axios.request(config):等同于axios(config)
axios.get(url[,config]):发get(获取)请求// 1. 第一个参数即是配置对象 axios({ url:"http://127.0.0.1/scoreList", params:{ age:12 }, headers:{ a:1, b:2, c:3 } }).then(value=>{ console.log(value.data); }) // 2. 第一个参数是请求地址,第二个参数是配置对象 axios.get("http://127.0.0.1/scoreList",{ params:{ age:12 }, headers:{ a:1 } }).then(({data})=>{ console.log(data); })
axios.delete(url[,config]):发delete(删除)请求//第二个参数是配置对象 axios.delete("http://127.0.0.1/scoreList/5",{ headers:{ c:3 }, params:{ num:1 }, data:{ a:1, b:2 } }).then(value=>{ console.log(value) })
axios.post(url[,data,config]):发post(添加)请求// 第一个参数是请求地址,第二个参数是请求体,第三个参数是配置对象 // application/json axios.post("http://127.0.0.1/scoreList",{ userName:"老薛头", age:78 },{ params:{ a:1, b:2 }, headers:{ userName:"wangwu" } }).then(value=>{ console.log(value.data); }) //urlencoded axios.post("http://127.0.0.1/scoreList","userName=小张&age=18",{ params:{ a:1, b:2 }, headers:{ userName:"wangwu" } }).then(value=>{ console.log(value.data); })
axios.put(url[,data,config]):发put(替换原数据)请求//第一个参数是请求地址,第二个参数是请求体,第三个参数是配置对象 //application/json axios.put("http://127.0.0.1/scoreList/3",{ userName:"老薛头", age:78 },{ params:{ a:1, b:2 }, headers:{ userName:"wangwu" } }).then(value=>{ console.log(value.data); }) //urlencoded axios.put("http://127.0.0.1/scoreList/4","userName=小张&age=18",{ params:{ a:1, b:2 }, headers:{ userName:"wangwu" } }).then(value=>{ console.log(value.data); })
axios.patch(url[,data[,config]]):发送patch(修改)请求// 第一个参数是请求地址,第二个参数是请求体,第三个参数是配置对象 axios.patch("http://127.0.0.1/scoreList/7",{ userName:"老薛头", age:78 },{ params:{ a:1, b:2 }, headers:{ userName:"wangwu" } }).then(value=>{ console.log(value.data); }) // urlencoded axios.patch("http://127.0.0.1/scoreList/4","userName=小张&age=18",{ params:{ a:1, b:2 }, headers:{ userName:"wangwu" } }).then(value=>{ console.log(value.data); })
axios.defaults.xxx:请求的默认全局配置axios.interceptors.request.use():添加请求拦截器axios.interceptors.response.use():添加响应拦截器axios.create([config]):创建一个新的axios实例var instance = axios.create({ baseURL:"https://some-domain.com/api/", timeout:1000, headers: {'X-Custom-Header':'foobar'} });
axios.CancelToken():用于创建取消请求的token对象axios.isCancel():是否是一个取消请求的错误axios.all(promises):用于批量执行多个异步请求
① 此方法接收的参数为——由Promise实例组成的数组。
② 返回的是一个Promise实例,只有数组中Promise状态都为成功时,才成功。
③ 当返回的Promise实例状态为成功时,值为数组(由数组中元素的成功值构成)axios.spread():用来指定接收所有成功数据的回调函数的方法
4.5 axios其他说明
- axios.baseURL:配置项中可设置url地址(协议+域名+端口),除路由部分(如/scoreList)
axios.get("/scoreList",{
// baseURL会同/scoreList进行拼接
baseURL:"http://127.0.0.1"
}).then(value=>{
console.log(value);
})
- timeoutchao:请求超时的时间设置,单位为毫秒ms,默认为0
axios.get("http://127.0.0.1/scoreList",{
timeout:3000 // 请求超时的时间,单位为毫秒,默认为0
}).then(value=>{
console.log(value);
})
- 取消请求:axios.CancelToken
axios.get("http://127.0.0.1/scoreList",{
//cancelToken为【取消请求token对象】创建的实例化对象
//接收一个回调函数,回调函数的参数为cancel
cancelToken:new axios.CancelToken(function(cancel){
//这里的cancel实则为成功回调函数
cancelHandler = cancel;
}),
params:{
age:12
}
}).then(value=>{
console.log(value.data);
})
- 全局默认配置
注意:地址如果不是以http://或https://开头(不是完整地址),那么会与baseURL进行拼接
如果是完整地址,不会与baseURL进行拼接
axios.defaults.baseURL = "http://127.0.0.1"
axios.defaults.timeout = 3000;
axios.defaults.headers.a = 100;
axios.defaults.params = {
num:1
}
- axios.create(config)
① 根据指定配置创建一个新的axios, 也就是每个新axios都有自己的配置
② 新axios只是没有取消请求和批量发请求的方法, 其它所有语法都是一致的
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="lib/axios.js"></script>
</head>
<body>
<button>engineer_why.com</button>
<button>127.0.0.1</button>
<button>127.0.0.1</button>
</body>
<script>
const btns = document.querySelectorAll("button");
// 项目一般使用到多少个服务,就需要创建多少个不同的axios实例
// 创建axios实例,并赋值给常量engineer_why. 后续可以将engineer_why替换axios
const engineer_why = axios.create({
// 该实例中的默认配置信息
baseURL:"http://engineer_why.com"
});
const local = axios.create({
baseURL:"http://127.0.0.1"
});
btns[0].onclick = function(){
engineer_why.get("/scoreList").then(value=>{
console.log(value.data)
})
}
btns[1].onclick = function(){
local.get("/scoreList").then(value=>{
console.log(value.data)
})
}
btns[2].onclick = function(){
local.get("/scoreList").then(value=>{
console.log(value.data)
})
}
</script>
</html>
- axios.spread:用来指定接收所有成功数据的回调函数的方法
// 原理
function spread(cb){
//value为一个数组
return function(value){
//apply是所有函数都有的方法
//apply允许我们将一个数组"解开",成为一个个的参数再传递给调用函数
cb.apply(null,value)
}
}
pp1 = Promise.all([p1,p2,p3])
console.log(pp1);
//输出为一个Promise对象,状态为成功,值为一个数组
pp1.then(value => console.log(value));//返回的是数组(长度为3)
//直接将接收的数组,根据apply语法解开,成功一个个参数(s1,s2,s3)
pp1.then(spread(function (s1,s2,s3){
console.log(s1,s2,s3);//获取到的是数组中的元素
}))
- 添加拦截器
① 拦截器可以设置多个:请求拦截先定义的后执行,响应拦截先定义的先执行
② 拦截器的本质是通过Promise.then串联起来的
③ 拦截器可以被移除。
- 请求拦截(先定义的后执行):axios.interceptors.request.use(()=>{})
请求拦截后,可以修改请求体内的信息,还可以编写需要的相关逻辑 - 响应拦截(先定义的先执行):axios.interceptors.response.use(()=>{})
响应体返回的值(return xxxx),即是请求成功后,得到的值(Promise成功的值)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="lib/axios.js"></script>
</head>
<body>
<button>get</button>
</body>
<script>
// 请求拦截:可以修改配置对象(重要)
axios.interceptors.request.use((config)=>{
// console.log("请求拦截",config);
config.params.age = 12;
config.headers.a = 100;
config.url = "http://127.0.0.1"+config.url;
// return config;
})
// 响应拦截:返回值即是axios请求后,得到的Promise成功值
axios.interceptors.response.use((res)=>{
return res.data;
})
document.querySelector("button").onclick = function(){
axios.get("/scoreList",{
params:{
age:10
}
}).then(value=>{
console.log(value);
})
}
//拦截器的本质是通过Promise.then串联起来的
Promise.resolve().then(请求拦截成功回调2,请求拦截失败回调2)
.then(请求拦截成功回调1,请求拦截失败回调1)
.then(发送请求函数,undefined)
.then(响应拦截成功回调1,响应拦截失败回调1)
.then(响应拦截成功回调2,响应拦截失败回调2)
</script>
</html>
- 移除拦截器
拦截器创建后,可以赋值给常量中,移除拦截器,通过常量名进行移除
axios.interceptors.request.eject(请求拦截器名);
axios.interceptors.response.eject(响应拦截器名);
- 响应体数据说明
config 配置项
data 响应体(实际最后要获取的数据)
headers 请求头
request 请求时创建的xhr实例
status 状态码
statusText 状态码说明
五、相关问题及回答总结
- 关于axios.get(url[,config])
- 第一个参数必须是地址,第二个参数配置项,可以不写。
- 关于catch与reject的使用
- 两者的参数均为回调函数,参数名为自定义
//回调内的参数err,可以自定义 catch(err=>{ console.log(err); })
- async和await的使用
- 一般情况下,await必须在async中使用
- await代表等待,它的右侧语句为
同步执行,下方语句为异步执行- await可以在script标签设置
type属性为module后单独使用- await右侧一般为Promise实例对象,执行后可得到实例的成功值
5794

被折叠的 条评论
为什么被折叠?



