八、axios学习
简介(为什么要用axios)
Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。
这里假设你已经学过Ajax和JQuery,你肯定会有疑问,它和Ajax有什么异同,和jQuery又有什么异同,先来看看ajax的简介——指一种创建交互式、快速动态网页应用的网页开发技术。
一般为了避免编写原生ajax出现的bug和简化代码,在以前我们更多的会使用JQuery封装好的ajax,众所周知,jQuery 是一个 JavaScript 库,它可以极大地简化 JavaScript 编程,也包括dom的操作,但是在vue中,也包含了对dom节点的操作,它基本包括了jquery的所有功能,所以,如果只是为了使用ajax而去引入jQuery,是不是有点杀鸡用牛刀,小题大做呢。
所以vue官方,出了一个和JQuery ajax相同功能的axios,免去为了使用异步网络请求而引入代码量巨大的JQuery
特性
- 从浏览器中创建 XMLHttpRequests
- 从 node.js 创建 http 请求
- 支持 Promise API
- 拦截请求和响应
- 转换请求数据和响应数据
- 取消请求
- 自动转换 JSON 数据
- 客户端支持防御 XSRF
安装
npm
1 | npm install axios |
cdn
1 | <script src="https://unpkg.com/axios/dist/axios.min.js"></script> |
初步使用
1 | //1.使用axios |
并发请求
axios.all([axios(),axios(),...])
axios.spread((res1,res2,...) => {...})
使用promise将它们关联起来
1 | //2.并发请求 |
简单默认配置
格式:
1 | //3.axios默认配置 |
常见配置
- 请求地址:
url: '/user'
, - 请求类型:
method: 'get
‘, - 请求根路径:
baseURL: 'http://www.mt.com/api'
, - 请求前的数据处理:
transformRequest:[function(data){}]
, - 请求后的数据处理:
transformResponse: [function(data){}]
, - 自定义的请求头:
headers:{'x-Requested-With':'XMLHttpRequest'}
, - URL查询对象:
params:{ id: 12 }
, - request body:
data: { key: 'aa'}
, - 查询对象序列化函数:
paramsSerializer: function(params){ }
- 超时设置s:
timeout: 1000
, - 跨域是否带Token:
withCredentials: false
, - 自定义请求处理:
adapter: function(resolve, reject, config){}
, - 身份验证信息:
auth: { uname: '', pwd: '12'
}, - 响应的数据格式 json / blob /document /arraybuffer / text / stream:
responseType: 'json'
,
实例
当我们从axios模块中导入对象时, 使用的实例是默认的实例.
当给该实例设置一些默认配置时, 这些配置就被固定下来了.
但是后续开发中, 某些配置可能会不太一样.
比如某些请求需要使用特定的baseURL或者timeout或者content-Type等.
这个时候, 我们就可以创建新的实例, 并且传入属于该实例的配置信息.
创建实例
1 | // 创建实例 |
封装axios
为什么要封装axios,假设这样一种情况,你的vue项目一直在用jQuery的ajax,不可避免的,你的很多个需要发起网络请求的组件都要使用到JQuery,但是突然又一天,上面要求整个项目弃用掉jQuery,改用axios,苦逼的事情就来了,你要把每个组件与jQuery相关的代码删除,然后替换成axios的网络请求模块,要是这是一个小项目还好,你需要改的组件只有几个,但如果这是一个大项目呢,上百个组件都要改,你就要一个一个去修改,打工人的加班就来了。而如果你将网络请求的代码的封装成一个文件,那么你就可以在下次需要更换插件时,只需修改封装的代码就行了。
总而言之,封装第三方插件是为了减少组件对其依赖,从而使组件的独立性以及可复用性可以更高
在src文件夹下新建network文件夹用来存放网络请求响应的相关文件,新建一个request.js作为请求文件
axios”封装史”
首先,引入axios模块(通用)以及创建封装函数
1 | import axios from 'axios' |
通过回调传递参数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17import axios from 'axios'
//第一种封装方式,通过回调传参数
export function request(config,success,failure) {
const a = axios.create({
baseURL: 'http://localhost:3000',
method: 'get',
timeout: 5000
})
te(config)
.then(res => {
success(res.data)
})
.then(err => {
failure(err)
})
}使用
1
2
3
4request('http://localhost:3000/middleschool',
res => {console.log(res)},
err => {if(err) console.log(err)}
)通过return一个Promise
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18//第二种方法,通过Promise
export function request(config) {
const te = axios.create({
baseURL: 'http://localhost:3000',
method: 'get',
timeout: 5000
})
return new Promise((resolve,reject) => {
te(config)
.then(res => {
resolve(res.data)
})
.catch(err => {
reject(err)
})
})
}然后这样做的好处就是你就可以在使用的时候then下去了
1
2
3
4request('http://localhost:3000/middleschool')
.then(res => {
console.log(res)
})最终版,其实,本来,axios本身就是支持Promis,所以我们何不直接把它return出去呢,这样代码会更加简单明了
1
2
3
4
5
6
7
8
9export function request(config) {
const te = axios.create({
baseURL: 'http://localhost:3000',
method: 'get',
timeout: 5000
})
return te(config)
}使用,同第二种是一样的
1
2
3
4request('http://localhost:3000/middleschool')
.then(res => {
console.log(res)
})拦截器
axios提供了拦截器,用于我们在发送每次请求或者得到相应后,进行对应的处理
使用
请求拦截
1 | te.interceptors.request.use(config => { |
响应拦截
1 | te.interceptors.response.use(res => { |
完整代码,注意:这是在封装中使用拦截器,还有,使用完,记得返回config/res,否则下一步无法继续
1 | //拦截器 |
结果:
作用
请求拦截器
- 发送网络请求时,在页面显示loading请求图标
- 在需要用户输入信息时(比如登录),判断用户是否有token,如没有,则会跳转到登录界面
- 对请求的参数进行序列化和修改
- 请求拦截中错误拦截较少,通常都是配置相关的拦截,可能的错误比如请求超时,可以将页面跳转到一个误页面中
响应拦截器
- 响应成功:主要是对数据进行过滤
- 响应失败:根据status判断报错的错误码,跳转到不同的错误提示页面