简介(为什么要用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
2
3
4
5
6
7
8
9
10
//1.使用axios
//使用方式axios(config)
//无指定,默认get请求
axios({
url:'http://localhost:3000/primaryschool'
}).then(res => {
console.log(res.data)
}).catch(err => {
console.log(err)
})

并发请求

axios.all([axios(),axios(),...])

axios.spread((res1,res2,...) => {...})

使用promise将它们关联起来

1
2
3
4
5
6
7
8
9
10
11
12
//2.并发请求
axios.all([
//指定get请求
axios.get('/primaryschool'),
axios({
//记得加上http://
url:'/middleschool'
})]).then(
axios.spread((res1,res2) => {
console.log(res1.data)
console.log(res2.data)
}))

简单默认配置

格式:

1
2
//3.axios默认配置
axios.defaults.baseURL = 'http://localhost:3000'

常见配置

  • 请求地址: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
2
3
4
5
6
7
8
9
10
11
12
// 创建实例
const a = axios.create({
baseURL: 'http://localhost:3000',
method: 'get',
timeout: 5000 //设定请求超时时间
})
// 发送网络请求
a({
url: '/middleschool'
}).then(res => {
console.log(res)
})

封装axios

为什么要封装axios,假设这样一种情况,你的vue项目一直在用jQuery的ajax,不可避免的,你的很多个需要发起网络请求的组件都要使用到JQuery,但是突然又一天,上面要求整个项目弃用掉jQuery,改用axios,苦逼的事情就来了,你要把每个组件与jQuery相关的代码删除,然后替换成axios的网络请求模块,要是这是一个小项目还好,你需要改的组件只有几个,但如果这是一个大项目呢,上百个组件都要改,你就要一个一个去修改,打工人的加班就来了。而如果你将网络请求的代码的封装成一个文件,那么你就可以在下次需要更换插件时,只需修改封装的代码就行了。

总而言之,封装第三方插件是为了减少组件对其依赖,从而使组件的独立性以及可复用性可以更高

在src文件夹下新建network文件夹用来存放网络请求响应的相关文件,新建一个request.js作为请求文件

axios”封装史”

首先,引入axios模块(通用)以及创建封装函数

1
2
3
4
5
6
import axios from 'axios'

//第一种封装方式,通过回调传参数
export function request(config) {
//......
}
  1. 通过回调传递参数

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    import 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
    4
    request('http://localhost:3000/middleschool',
    res => {console.log(res)},
    err => {if(err) console.log(err)}
    )
  2. 通过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
    4
    request('http://localhost:3000/middleschool')
    .then(res => {
    console.log(res)
    })
  3. 最终版,其实,本来,axios本身就是支持Promis,所以我们何不直接把它return出去呢,这样代码会更加简单明了

    1
    2
    3
    4
    5
    6
    7
    8
    9
    export function request(config) {
    const te = axios.create({
    baseURL: 'http://localhost:3000',
    method: 'get',
    timeout: 5000
    })

    return te(config)
    }

    使用,同第二种是一样的

    1
    2
    3
    4
    request('http://localhost:3000/middleschool')
    .then(res => {
    console.log(res)
    })

    拦截器

axios提供了拦截器,用于我们在发送每次请求或者得到相应后,进行对应的处理

使用

请求拦截

1
2
3
4
5
6
7
te.interceptors.request.use(config => {
console.log(config)
console.log('这里是请求拦截器')
return config //记得返回
},err => {

})

响应拦截

1
2
3
4
5
6
7
te.interceptors.response.use(res => {
console.log(res)
console.log('这里是响应拦截器')
return res
}, err => {

})

完整代码,注意:这是在封装中使用拦截器,还有,使用完,记得返回config/res,否则下一步无法继续

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
//拦截器
export function request(config) {
const te = axios.create({
baseURL: 'http://localhost:3000',
method: 'get',
timeout: 5000
})

te.interceptors.request.use(config => {
console.log(config)
console.log('这里是请求拦截器')
return config //记得返回
},err => {

})

te.interceptors.response.use(res => {
console.log(res)
console.log('这里是响应拦截器')
return res
}, err => {

})

return te(config)
}

结果:

image-20201031162642133

作用

请求拦截器

  1. 发送网络请求时,在页面显示loading请求图标
  2. 在需要用户输入信息时(比如登录),判断用户是否有token,如没有,则会跳转到登录界面
  3. 对请求的参数进行序列化和修改
  4. 请求拦截中错误拦截较少,通常都是配置相关的拦截,可能的错误比如请求超时,可以将页面跳转到一个误页面中

响应拦截器

  1. 响应成功:主要是对数据进行过滤
  2. 响应失败:根据status判断报错的错误码,跳转到不同的错误提示页面