🚞 axios 在 Vue 项目中的封装
axios
拥有友好的 API 调用,可以轻松在项目中直接使用。但是随着项目规模越大,如果每发起一次 HTTP 请求,都要进行一遍一遍如 超时时间、请求头、请求地址、错误处理等的重复配置,不仅浪费时间而且让代码变得冗余。
# 封装的内容
在发送请求之前,应该要与后端协商好 请求头、协议、请求地址、请求超时时间的约定。以便对 axios 进行进一步的封装一下内容:
- 设置接口请求的前缀。 根据开发、测试、生产的三种不同环境,分别配置不同的请求地址前缀。
- 请求头。例如用户登录状态的验证,在每次发送请求中的请求头中添加 token;或者在请求头中携带一些参数。
- 状态码。根据接口返回不同的
status
,执行不同的业务。 - 请求方法。对
get
、post
等方法进行再一次封装。 - 请求拦截器:根据请求的请求头决定,决定哪些请求可以访问。
- 响应拦截器:根据后端返回的状态码判断执行不同的业务。
# 设置接口的前缀
通常方法。根据 node
环境变量判断区分开发、测试、生产环境。
if (process.env.NODE_ENV === 'development') {
axios.defaults.baseURL = 'http://dev.xxx.com'
} else if (process.env.NODE_ENV === 'production') {
axios.defaults.baseURL = 'http://prod.xxx.com'
}
1
2
3
4
5
2
3
4
5
在本地开发调试时,配置代理服务器
devServer
:devServer: { proxy: { '/proxyApi': { target: 'http://dev.xxx.com', changeOrigin: true, pathRewrite: { '/proxyApi': '' } } } } }
1
2
3
4
5
6
7
8
9
10
11
12
# 设置请求头与超时时间
大部分情况下,请求头都是固定的,只有少部分情况下,会需要一些特殊的请求头。这里设置的是基础的请求头。当需要特殊的请求头时,再将特殊的请求头作为参数传入,覆盖基础配置。
const service = axios.create({
...
timeout: 30000, // 请求 30s 超时
headers: {
get: {
'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8'
// 在开发中,一般还需要单点登录或者其他功能的通用请求头,可以一并配置进来
},
post: {
'Content-Type': 'application/json;charset=utf-8'
// 在开发中,一般还需要单点登录或者其他功能的通用请求头,可以一并配置进来
}
},
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
# 封装请求方法
// get 请求
export function httpGet({
url,
params = {}
}) {
return new Promise((resolve, reject) => {
axios.get(url, {
params
}).then((res) => {
resolve(res.data)
}).catch(err => {
reject(err)
})
})
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
export function httpPost({
url,
data = {},
params = {}
}) {
return new Promise((resolve, reject) => {
axios({
url,
method: 'post',
transformRequest: [function (data) {
let ret = ''
for (let it in data) {
ret += encodeURIComponent(it) + '=' + encodeURIComponent(data[it]) + '&'
}
return ret
}],
// 发送的数据
data,
// url参数
params
}).then(res => {
resolve(res.data)
})
})
}
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
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
import { httpGet, httpPost } from './http'
export const getorglist = (params = {}) => httpGet({ url: 'apps/api/org/list', params })
1
2
2
# 请求拦截器
这里以在每次请求之前添加 token
为例子。设置如下的拦截器:
axios.interceptors.request.use(
config => {
// 每次发送请求之前判断是否存在token
// 如果存在,则统一在http请求的header都加上token,这样后台根据token判断你的登录情况,此处token一般是用户完成登录后储存到localstorage里的
token && (config.headers.Authorization = token)
return config
},
error => {
return Promise.error(error)
})
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
# 响应拦截器
响应拦截器可以在接收到响应之后先完成一系列的逻辑。
这里以根据状态码判断登录状态、授权,处理错误为例:
// 响应拦截器
axios.interceptors.response.use(response => {
// 如果返回的状态码为200,说明接口请求成功,可以正常拿到数据
// 否则的话抛出错误
if (response.status === 200) {
if (response.data.code === 511) {
// 未授权调取授权接口
} else if (response.data.code === 510) {
// 未登录跳转登录页
} else {
return Promise.resolve(response)
}
} else {
return Promise.reject(response)
}
}, error => {
// 我们可以在这里对异常状态作统一处理
if (error.response.status) {
// 处理请求失败的情况
// 对不同返回码对相应处理
return Promise.reject(error.response)
}
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
编辑 (opens new window)
📢 上次更新: 2022/09/02, 10:18:16