Axios新版学习大纲
Axios入门
HTTP相关
MDN文档
https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Overview
HTTP请求报文
请求行
格式: method url
例如: GET/product_detail?id=2 或 POST / login
请求头(一般有多个请求头)
Host: www.baidu.com
Cookie: BAIDUID=AD3B0FA706E;BIDUPSID=AD3B0FA706;
Content-Type: applicartion/x-www-from-urlencoded 或者 application/json
请求体 (get没有)
username=tom&pwd=123
{“username”:”tom”,”pwd”:123}
HTTP响应报文
响应行
格式: status status Text
例如: 200 OK 或 404 Not Found
响应头(一般有多个)
Content-Type:text/html;charset=utf-8
Set-Cookie:BD_CK_SAM=1;PATH=/
响应体
html/json/js/css/图片
常见的状态码
200 OK 请求成功.。一般用于GET/POST请求
201 Created 已创建。成功请求并创建了新的资源
401 Unauthorized 未授权/请求用户的身份证
404 Not Found 服务器无法根据客户端请求找到资源
500 internal Serve Error 服务器内部错误,无法完成请求
请求方式与请求参数
请求方式
GET(索取):从服务端读取数据 —– 查(R –Retrieve)
POST(交差):向服务端添加新数据 —– 增(C –Create)
PUT:更新服务端已经存在的数据 —— 改(U –Update)
DELETE:删除服务器端数据 —— 删(D –Delete)
请求参数
query参数(查询字符串参数)
- 参数包含在请求地址中,格式为:/xxxx?name=tom&age=18
- 敏感数据不要用query参数,因为参数是地址的一部分,比较危险
- 备注:query参数又称为查询字符串参数,编码方式为urlencoded
params参数
参数包含在请求地址中,格式如下:
敏感数据不要用params参数,因为参数是地址的一部分,比较危险
请求体参数(body)
参数包含在请求体中,可通过浏览器开发工具查看
常用的两种格式:
格式一:urlencoded格式
例如:name=tom&age=18
对于请求头:Content-Type:application/x-www-from-urlencoded
格式二:json格式
例如:{“name”:”tom”,”:age”:12}
对应请求头:Content-Type:application/json
特别注意:
GET请求不能携带请求体参数,因为GET请求没有请求体
理论上一次请求可以随意使用上述3种类型参数中的任何一种,甚至一次请求的3个参数可以用3种形式携带,但一般不这样做
一般来说我们有一些”约定俗成”的规矩:
(1):例如 from 表单发送 post 请求时,自动使用请求体参数,用urlencoded编码
(2):例如 jQuery 发送ajax-post请求时,自动使用请求体参数,用urlencoded编码
- 开发中请求到底发给谁?用什么方式? 携带什么参数? —要参考项目的API接口文档
API相关
API的分类
REST API(restful 风格的 API)
发送请求进行 CRUD(增查改删) 哪个操作由请求方式来决定
同一个请求路径可以进行多个操作
请求方式会用到 GET / POST / PUT / DELETE
const express = require('express') // 实例一个app服务对象 const app = express() app.get('/person',(req,res)=>{ res.send('一些人的数据给你了') }) app.post('/person',(req,res)=>{ res.send('你成功的添加了一个人') }) app.put('/person',(req,res)=>{ res.send('你成功的修改了一个人') }) app.post('/person',(req,res)=>{ res.send('你成功的删除了一个人') }) app.listen(8090,(error)=>{ if(!error) console.log('服务器开启成功了'); })
非 REST API (restless 风格的 API)
- 请求方式不决定请求的 CRUD 操作
- 一个请求路径只对应一个操作
- 一般只有 GET / POST
// 早些年都这么写,两个请求有4个路径 --不能清晰表达要干嘛
const express = require('express')
// 实例一个app服务对象
const app = express()
app.get('/get_person',(req,res)=>{
res.send('一些人的数据给你了')
})
app.post('/add_person',(req,res)=>{
res.send('你成功的添加了一个人')
})
app.post('/update_person',(req,res)=>{
res.send('你成功的修改了一个人')
})
// 请求方式不决定请求的 CRUD 操作
app.post('/delete_person',(req,res)=>{
res.send('你成功的删除了一个人')
})
app.listen(8090,(error)=>{
if(!error) console.log('服务器开启成功了');
})
使用 json-server 搭建 REST API
json-server是什么?
- 用来快速搭建REST API 风格的工具包
使用 json-server
在线文档:http:github.com/typicode/json-serrver
下载:npm install -g json-server
{ "posts": [ { "id": 1, "title": "json-server", "author": "typicode" } ], "comments": [ { "id": 1, "body": "some comment", "postId": 1 } ], "profile": { "name": "typicode" } }- 目标根目录下创建数据库 **json** 文件:**db.json**
- 启动服务器执行命令:json-server --watch db.json (watch可以省略 db可以改为任意喜欢的名字) #### 使用浏览器访问测试 http://localhost:3000/posts http://localhost:3000/comments http://localhost:3000/profile #### 使用postmon接口测试 **json-server服务器注意:** - postmon测试中发送PUT请求,能在请求体携带id参数(或者使用params携带id),不能用query参数携带id - postmon测试中发送DELETE请求,只能使用params携带参数(json-server模拟的服务器,id都得通过params携带,其他有请求体就用请求体,没有就正常使用params或者query) #### 一般 http 请求与 ajax 请求 - ajax请求是一种特别http请求 - 对服务器端来说,没有任何区别,区别在浏览器端 - 浏览器端发请求:只有XHR或fetch发出得才是ajax请求。其他所有得都是非ajax请求 - 浏览器端接收到响应 (1) 一般请求:浏览器一般会直接显示响应体数据,也就是我们常说得自动刷新/跳转页面 (2)ajax 请求:浏览器不会对界面进行任何更新操作,只是调用监视得回调函数传入响应相关数据 ## axios的理解和使用 ### axios是什么 1.前端最流行的ajax请求库 2.react/vue官方都推荐使用axios发ajax请求 3.文档:https://github.com/axios/axios ### axios特点 1.基于Promise的异步ajax请求库 2.浏览器端/node端都可以使用 3.支持请求/响应拦截器 4.支持请求取消 5.请求/响应数据转换 6.批量发送多个请求 ### 使用axios发送ajax请求 - 终端打开准备好的server文件夹里使用api-doc工具制作的api文档 - 新建 '1_axios的基本使用.html' 文件,同时新建一个js文件夹存放axios.mini.js文件,引入到html里 **准备按钮、文本框** ```html <button id="btn1">点我获取所有人</button><br><br> <button id="btn2">点我获取某个人</button> <input id="person_id" type="text" placeholder="请输入一个人的id"><br><br> <button id="btn3">点我添加一个人</button> <input id="person_name" type="name" placeholder="请输入一个人的名字"> <input id="person_age" type="age" placeholder="请输入一个人的年龄"><br><br> <button id="btn4">点我更新一个人</button> <input id="person_update_id" type="text" placeholder="请输入一个人的id"> <input id="person_update_name" type="text" placeholder="请输入名字"> <input id="person_update_age" type="text" placeholder="请输入年龄"><br /><br /> <button id="btn5">点我删除一个人</button> <input id="person_delete_id" type="text" placeholder="请输入删除的id">
获取按钮、文本框
const btn1 = document.getElementById('btn1')
const btn2 = document.getElementById('btn2')
const btn3 = document.getElementById('btn3')
const personId = document.getElementById('person_id')
const personName = document.getElementById('person_name')
const personAge = document.getElementById('person_age')
const btn4 = document.getElementById('btn4')
const btn5 = document.getElementById('btn5')
const personUpdateId = document.getElementById('person_update_id')
const personUpdateName = document.getElementById('person_update_name')
const personUpdateAge = document.getElementById('person_update_age')
const personDeleteId = document.getElementById('person_delete_id')
获取所有人的信息 —发送GET请求 —不携带参数
// 获取所有人的信息 ---发送GET请求 ---不携带参数
btn1.onclick = () => {
// 完整版
axios({
url: 'http://localhost:5000/persons', //请求地址
method: 'GET', //请求方式
}).then(
(response) => { console.log('请求成功了',response.data)},
(error) => { console.log('请求失败了',error) }
)
// 精简版
axios.get('http://localhost:5000/persons').then(
response => {console.log('请求成功了',response.data)},
error => {console.log('请求失败了',error)}
)
}
// 如果只想获取到成功的值 可以使用await 方法更简单
btn1.onclick = async() => {
const result = await axios.get('http://localhost:5000/persons')
console.log(result.data)
}
使用axios发送其他请求
发送GET请求
获取某个人—发送GET请求—携带query参数
//获取某个人---发送GET请求---携带query参数
btn2.onclick = () => {
// 完整版
axios({
url: 'http://localhost:5000/person',
method: 'GET',
params: { id: personId.value }//此处写的是params,但携带的是query参数
}).then(
response => {
console.log('请求成功了', response.data);
},
error => { '请求失败了', error }
)
// 精简版
axios.get('http://localhost:5000/person', { params: { id: personId.value } }).then(
response => { console.log('成功了', response.data); },
error => { console.log('失败了', error); }
)
}
发送POST请求
添加一个人—发送POST请求—携带json编码参数 或 urlencoded编码
btn3.onclick = ()=> {
axios({
// 完整版
url:'http://localhost:5000/person',
method:'POST',
data:{name:personName.value,age:personAge.value} //携带请求体参数(json编码)
}).then(
response => {
console.log('请求成功了', response.data);
},
error => {
console.log('请求失败了', error);
}
)
// 精简版
axios.post('http://localhost:5000/person',`name=${personName.value}&age=${personAge.value}`).then(
// axios.post('http://localhost:5000/person',{name:personName.value,age:personAge.value}).then(
response => {console.log('请求成功了',response.data)},
error => {console.log('请求失败了',error)}
)
}
发送PUT请求
更新一个人—发送PUT请求—携带json编码参数 或 urlencoded编码
btn4.onclick = () => {
// 完整版
axios({
url: 'http://localhost:5000/person',
method: 'PUT',
data: {
id:personUpdateId.value,
name:personUpdateName.value,
age:personUpdateAge.value
},
}).then(
response => {
console.log('请求成功了', response.data);
},
error => {
console.log('请求失败了', error);
}
)
//精简版
axios.put('http://localhost:5000/person',{
id:personUpdateId.value,
name:personUpdateName.value,
age:personUpdateAge.value
}).then(
response => { console.log('请求成功了', response.data) },
error => { console.log('请求失败了', error) }
)
}
发送DELETE请求
删除一个人—发送DELETE请求—携带params参数
btn5.onclick = ()=> {
axios({
url:`http://localhost:5000/person/${personDeleteId.value}`,
method:'DELETE',
}).then(
(response)=>{console.log('请求成功了',response.data);},
(error)=>{console.log('请求失败了',error);}
)
}
结论
axios调用的返回值是Promise实例
成功的值叫response,失败的值叫error
axios成功的值是一个axios封装的response对象,服务器返回的真正数据在response.data中
携带query参数时,编写的配置项叫做params
携带params参数时,就需要自己手动拼在url中
axios常用配置项
新建‘2_axios常用配置项.html’文件,引入‘axios.min.js’
<button id="btn">点我获取所有人</button><br/><br/>
<script type="text/javascript" >
const btn = document.getElementById('btn')
//给axios配置默认属性
axios.defaults.timeout = 2000
axios.defaults.headers = {school:'atguigu'}
axios.defaults.baseURL = 'http://localhost:5000'
btn.onclick = ()=>{
axios({
url:'/persons', //请求地址
method:'GET',//请求方式
//params:{delay:3000},//配置query参数
//data:{c:3,d:3},//配置请求体参数(json编码)
//data:'e=5&f=6',//配置请求体参数(urlencoded编码)
//timeout:2000,//配置超时时间
//headers:{school:'atguigu'} //配置请求头
//responseType:'json'//配置响应数据的格式(默认值)
}).then(
response => {console.log('成功了',response.data);},
error => {console.log('失败了',error);}
)
}
</script>
axios常用语法
新建’3_axios.create方法.html‘,引入‘axios.min.js’
axios.create(config)
根据指定配置创建一个新的axios, 也就是每个新axios都有自己的配置
新axios只是没有取消请求和批量发请求的方法, 其它所有语法都是一致的
为什么要设计这个语法?
需求: 项目中有部分接口需要的配置与另一部分接口需要的配置不太一样
<button id="btn3">点我获取笑话信息</button><br/><br/>
<script type="text/javascript" >
const btn3 = document.getElementById('btn3')
// 创建一个新的axios
const axios2 = axios.create({
timeout:3000,
//headers:{name:'tom'},
baseURL:'https://api.apiopen.top/api'
})
//给原axios配置默认属性
axios.defaults.timeout = 2000
axios.defaults.headers = {school:'atguigu'}
axios.defaults.baseURL = 'http://localhost:5000'
btn3.onclick = ()=>{
axios2({
url:'/getImages',
method:'GET'
}).then(
response => {console.log('成功了',response.data);},
error => {console.log('失败了',error);}
)
}
</script>
拦截器函数/ajax请求/请求的回调函数
axios请求拦截器
1.是什么?
在真正发请求前执行的一个回调函数
2.作用:
对所有的请求做统一的处理:追加请求头、追加参数、界面loading提示等等
新建’4_axios中的拦截器.html‘,引入‘axios.min.js’
<button id="btn">点我获取所有人</button><br/><br/>
<script type="text/javascript" >
const btn = document.getElementById('btn')
//请求拦截器
axios.interceptors.request.use((config)=>{
console.log('请求拦截器1执行了');
// 如果时间戳是偶数 就加上请求头
if(Date.now() % 2 === 0){
config.headers.token = 'atguigu'
}
console.log(config);
return config
})
btn.onclick = ()=>{
axios.get('http://localhost:5000/persons').then(
response => {console.log('成功了',response.data)},
error => {console.log('失败了',error);}
)
}
</script>
axios响应拦截器
1.是什么?
得到响应之后执行的一组回调函数
2.作用:
若请求成功,对成功的数据进行处理
若请求失败,对失败进行统一的操作
<button id="btn">点我获取所有人</button><br/><br/>
<script type="text/javascript" >
const btn = document.getElementById('btn')
//响应拦截器
axios.interceptors.response.use(
response => {
console.log('响应拦截器成功的回调执行了',response);
if(Date.now() % 2 === 0) {
return response.data
} else {
return '时间戳不是偶数,不能给你数据'
}
},
error => {
console.log('响应拦截器失败的回调执行了');
alert(error);
return new Promise(()=>{})
}
)
btn.onclick = async ()=>{
const result = await axios.get('http://localhost:5000/persons2')
console.log(result);
}
</script>
取消请求
<button id="btn">点我获取测试数据</button><br/><br/>
<button id="btn2">取消请求</button><br/><br/>
<script type="text/javascript" >
const btn = document.getElementById('btn')
const btn2 = document.getElementById('btn2')
const {CancelToken} = axios //CancelToken能为一次请求“打标识”
let cancel
btn.onclick = async()=>{
axios({
url:'http://localhost:5000/test1?delay=3000',
cancelToken:new CancelToken((c)=>{ //c是一个函数,调用c就可以关闭本次请求
cancel = c
})
}).then(
response => {console.log('成功了',response.data);},
error => {console.log('失败了',error);}
)
}
btn2.onclick = ()=>{
cancel()
}
</script>
取消请求和拦截器配合使用
<button id="btn">点我获取测试数据</button><br/><br/>
<button id="btn2">取消请求</button><br/><br/>
<script type="text/javascript" >
const btn = document.getElementById('btn')
const btn2 = document.getElementById('btn2')
// axios里面有个isCancel方法专门用于判断错误,还是用户取消请求导致的不合理。使用{}取出isCancel
const {CancelToken,isCancel} = axios //CancelToken能为一次请求“打标识”
let cancel
btn.onclick = async()=>{
// 每次点击按钮的时候都问一下外边是否有cancel 有没有值
if(cancel){
cancel()
}
axios({
url:'http://localhost:5000/test1?delay=3000',
cancelToken:new CancelToken((c)=>{ //c是一个函数,调用c就可以关闭本次请求
cancel = c
})
}).then(
response => {console.log('成功了',response.data);},
error => {
if(isCancel(error)){
//如果进入判断,证明:是用户取消了请求
console.log('用户取消了请求,原因是:',error.message);
}else{
console.log('失败了',error);
}
}
)
}
btn2.onclick = ()=>{
cancel('任性,就是不要了')
}
</script>
<button id="btn">点我获取测试数据</button><br/><br/>
<button id="btn2">取消请求</button><br/><br/>
<script type="text/javascript" >
const btn = document.getElementById('btn')
const btn2 = document.getElementById('btn2')
const {CancelToken,isCancel} = axios //CancelToken能为一次请求“打标识”
let cancel
axios.interceptors.request.use((config)=>{
if(cancel) cancel('取消了')
config.cancelToken = new CancelToken((c)=> cancel= c)
return config
})
axios.interceptors.response.use(
response => {return response.data},
error => {
if(isCancel(error)){
//如果进入判断,证明:是用户取消了请求
console.log('用户取消了请求,原因是:',error.message);
}else{
console.log('失败了',error);
}
return new Promise(()=>{})
}
)
btn.onclick = async()=>{
const result = await axios.get('http://localhost:5000/test1?delay=3000')
console.log(result);
}
btn2.onclick = ()=>{
cancel('任性,就是不要了')
}
</script>
批量的发送请求
<script type="text/javascript" >
const btn = document.getElementById('btn')
btn.onclick = async()=>{
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(error);}
)
}
</script>