axios强大的ajax请求库

前言

json-server

用来搭建REST API的工具包

XHR

XMLHttpRequest允许无需让整个页面刷新,更新局部内容

区别一般http请求与ajax请求

ajax请求是一种特别的http请求
对服务器端来说,没有区别。区别在浏览器端,
浏览器端发请求:只有XHR或fetch发出的才是ajax请求,其他所有都是非ajax请求

一.认识axios

axios
是前端最流行的ajax请求库
特点:
1.返回对象为promise,异步
2.支持浏览器端,还支持node端
浏览器发的才有可能是ajax请求,服务器端发的叫http请求
3.支持请求/响应拦截器
4.支持请求取消
5.请求/响应数据转换
6.批量发送多个

axios的常见配置
url,method,data(封装请求体),params(封装query)

请求出错或者被取消—yes—-rejected
—no—fulfilled,要打印出错信息用resolved

语法糖:进行包装的简洁语法

注意:如果对象是对象类型,axios默认json发

可以作为对象,调用方法发请求axios.post 也可以作为函数发请求axios({})
配置对象:属性名固定,每个属性的作用也固定

axios原生拼接url

1
2
3
4
5
6
7
8
9
10
11
12
//处理query参数(拼接到url上)
let queryString = ''
Object.keys(params).forEach(key => {
queryString += `${key}=${params[key]}&` //注意此处为反引号
})
if(queryString) {
//没有参数的时候,去掉最后的&  
//subString会产生一个新的
queryString = queryString.substring(0,queryString.length-1)
//拼接到url
url += '?'+queryString
}

02.html注意观察,已经实现跨域了(除了get 因为get不修改),通过cors,跨域的请求浏览器会出于安全的考虑,会先发一个预检的请求

发get请求,需要传params提交query参数,处理query参数进行url拼接,request.send()返回即可

发送post请求,需要提交请求体参数data,设置请求头信息
request.setRequestHeader(‘Content-Type’,’application/json;charaset=utf-8’)
request.send(JSON.stringify(data)) //发送json格式请求体参数

1.axios二次封装

因为axios本身就是对ajax用xhr的封装
再对其进行封装就是二次
实质是对ajax请求的二次封装,axios只是一次封装

2.方法

axios.defaults.baseURL

指定基本路径

axios.create

解决:
发多个不同端口,不同端口使用不同的配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/
 axios.defaults.baseURL = "http://localhost:3000"
//使用axios发
axios({
url: '/posts'
})  //去请求3000
// axios({
//     url: '/xxx'
// })  //去请求4000
const instance = axios.create({
baseURL: 'http://localhost:4000'
})
//使用instance发
instance({
url: '/xxx' //去请求4000
})
//更简洁的方式
instance.get('/xxx')

如果有3个请求,至少创建2个create

3.拦截器

拦截器本质是回调函数

  • axios.interceptors.request.use()
  • axios.interceptors.response.use()

请求拦截器后添加先执行,响应拦截器先添加先执行为啥?去看源码
因为请求插入用的是unshift前插,而响应用的是push后插

拦截器.png

执行顺序:
request2
request1
response1
response2
axios发的get请求

4.取消请求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
let cancel  //用于保存取消请求的函数
axios({
url: 'http://localhost:/posts',
cancelToken: new axios.CancelToken((c) => {
//c是用于取消当前请求的函数
//保存取消函数,用于之后可能需要取消当前请求
cancel = c
})
}).then(
response => {
cancel = null
console.log("成功");
},
error => {
console.log('请求1失败了',error.message,error);
}
)
if(typeof cancel === 'function'){
//执行取消请求的函数
cancel('强制取消')
}else{
console.log("没有可取消的请求");
}

点击取消之后的执行顺序:
请求1失败了
强制取消
Cancel{}

即取消之后先调用请求自身的error处理,然后执行cancel取消函数。并把cancel传给error,此时error是一个cancel函数

axios.isCancel() 判断是否为cancel类型

中断promise,可以用return new Promise(() => {})
将错误向下传递,可以用return Promise.reject(error)

二.源码分析–核心

1.request(config)

将请求拦截器/dispatchRequest()/响应拦截器 通过promise链串起来 返回promise
shift是取第一个
Image.png

每一个回调函数就相当于一个任务,通过promise链将他们串联起来
Promise链.png

2.dispatchRequest(config)

用来转换请求数据–>调用xhrAdapter()发请求–》请求返回后转换响应数据,返回promise
Promise链.png

  • 请求转换器
    如果data是对象—->将指定请求参数格式设为json setContentTypeIfUnset(headers,'application/json;charaset=utf-8'),并将参数的数据对象转换为jsonreturn JSON.stringify(data)

    • 有些不支持json的服务器如何进行解决
      如果data是对象,会将其转化为json格式,但是有些服务器不支持json,因此用到请求拦截器将其转化为urlencoded格式
  • 响应转化器
    解析字符串类型的data数据
    (JSON.parse()是将json格式转化为js)
    不进行判断data是否为json格式,将data直接JSON.parse(),捕获异常,但是不进行处理

3.xhrAdapter(config)

创建xhr对象,根据config进行配置,发送特定请求,并接收响应数据,返回promise

4.axios流程图

流程图.png