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的工具包

2.2 使用json-server:提供数据的模拟响应
  1. 首先要安装Node
    由于json-server需要通过Node对其进行启动,所以要先安装Node
  2. 全局安装json-server
    npm install json-server -g
  3. 查看版本
    json-server -v
  4. 准备一份JSON文件:必须是一个对象,不能是数组
  5. 启动的相关命令

--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请求
  1. ajax请求是一种特别的http请求。
  2. 对服务器端来说,没有任何区别,区别再浏览器端。
  3. 浏览器端发请求:只有XHR或fetch发出的才是ajax请求,其它的所有的请求都是非ajax请求。
  4. 浏览器端接收到响应
    (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的特点
  1. fetch是windows对象下的方法
  2. fetch返回的是一个Promise实例
  3. 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);// 响应体的数据
	})
})

代码说明:

  1. 通过fetch请求数据>>>获得是一个成功的Promise实例,值为一个Response对象
  2. 然后通过then方法,获取到成功值Response
  3. 使用Response原型链上的json方法,获取到响应体数据

四、axios的理解和使用(重点)

4.1 axios是什么?
  1. 前端最流行的ajax请求库,没有之一
  2. react/vue官方都推荐使用axios发ajax请求
  3. 文档:axios在线文档
4.2 axios的特点
  1. 基于xhr+promise的ajax请求库
  2. 浏览器端和node端都可以使用
  3. 支持请求和响应拦截器(重点
  4. 支持请求取消
  5. 支持批量发送多个请求
4.3 axios常用语法
  1. 引入axios.js
cnpm install axios -S     //-S相当于--save 开发中的框架
  1. 再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其他说明
  1. axios.baseURL:配置项中可设置url地址(协议+域名+端口),除路由部分(如/scoreList)
axios.get("/scoreList",{
// baseURL会同/scoreList进行拼接
	baseURL:"http://127.0.0.1"
}).then(value=>{
	console.log(value);
})
  1. timeoutchao:请求超时的时间设置,单位为毫秒ms,默认为0
axios.get("http://127.0.0.1/scoreList",{
	timeout:3000 // 请求超时的时间,单位为毫秒,默认为0
}).then(value=>{
	console.log(value);
})
  1. 取消请求: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);
})
  1. 全局默认配置
    注意:地址如果不是以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
}
  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>
  1. 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);//获取到的是数组中的元素
}))
  1. 添加拦截器
    ① 拦截器可以设置多个:请求拦截先定义的后执行,响应拦截先定义的先执行
    ② 拦截器的本质是通过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>
  1. 移除拦截器
    拦截器创建后,可以赋值给常量中,移除拦截器,通过常量名进行移除
axios.interceptors.request.eject(请求拦截器名);
axios.interceptors.response.eject(响应拦截器名);
  1. 响应体数据说明
    config 配置项
    data 响应体(实际最后要获取的数据)
    headers 请求头
    request 请求时创建的xhr实例
    status 状态码
    statusText 状态码说明

五、相关问题及回答总结

  1. 关于axios.get(url[,config])
  • 第一个参数必须是地址,第二个参数配置项,可以不写。
  1. 关于catch与reject的使用
  • 两者的参数均为回调函数,参数名为自定义
//回调内的参数err,可以自定义
catch(err=>{
		console.log(err);
})
  1. async和await的使用
  • 一般情况下,await必须在async中使用
  • await代表等待,它的右侧语句为同步执行,下方语句为异步执行
  • await可以在script标签设置type属性为module后单独使用
  • await右侧一般为Promise实例对象,执行后可得到实例的成功值
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

engineer_why

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值