在 Vue 3 项目中,拦截器(Interceptors)主要指 Axios 拦截器,它充当了前端应用与后端服务器之间的一个中间件层。其核心作用是在请求发送前或响应接收后,对数据进行统一拦截和处理。
具体来说,Vue 3 项目中的拦截器主要有以下四大核心作用:
1. 请求拦截器(Request Interceptor)
在请求发送到服务器之前进行统一处理,避免在每个业务接口中重复编写相同的逻辑:
- 身份验证与授权 :自动从本地存储(如
localStorage)读取 Token,并添加到每个请求的 Header 中,确保用户处于登录状态。 - 全局配置注入:统一设置请求超时时间、Content-Type 格式,或添加特定的公共请求参数。
- 全局 Loading 状态:在请求发出时触发全局的加载动画(Loading),提示用户正在获取数据。
- 数据预处理:对敏感请求参数进行加密处理,或格式化请求数据结构。
2. 响应拦截器(Response Interceptor)
在接收到服务器响应之后 、业务代码处理数据之前进行统一处理:
- 统一数据格式化 :剥离响应中无用的外层包装(如
{code: 200, msg: 'ok', data: {...}}),直接提取data返回给业务组件,简化业务代码。 - 全局 Loading 关闭:请求完成后,自动关闭之前开启的加载动画。
- 业务状态码处理 :根据后端返回的自定义状态码(如
code != 200)进行统一拦截,例如提示错误信息或执行特定的业务逻辑。
3. 全局错误处理
拦截器可以捕获网络请求中出现的各类异常,并进行统一的兜底处理,大幅提升用户体验和代码的健壮性:
- HTTP 状态码处理 :例如捕获
401 Unauthorized状态码,自动清除本地 Token 并重定向到登录页面;捕获403提示权限不足;捕获500提示服务器异常。 - 网络异常处理:处理断网、请求超时等网络错误,给出友好的全局 Toast 提示。
4. 提升代码质量与可维护性
- 消除冗余代码:将鉴权、错误提示、数据格式化等通用逻辑从具体的业务组件中抽离出来,使得组件代码更加纯粹和简洁。
- 增强复用性:只需在 Axios 实例中配置一次拦截器,整个 Vue 3 项目中的所有接口请求都会自动生效,极大地提高了开发效率和代码的可维护性。
补充说明:除了 Axios 拦截器,Vue 3 项目中还有 Vue Router 导航守卫(Navigation Guards)。它主要用于拦截页面的路由跳转,常用于页面级别的权限验证(如未登录禁止访问后台页面)、页面标题设置或数据预加载等。两者结合使用,可以构建非常完善的前端安全与交互体系。
下面是一个拦截器的例子:
src/api/request.js
js
import axios from 'axios'
// 创建axios实例
const service = axios.create({
baseURL: '/api', // 公共基础地址
timeout: 10000, // 请求超时时间 10秒
})
// 请求拦截器:发请求之前做处理,比如携带token
service.interceptors.request.use(
config => {
// 动态判断:只有不是FormData,才设置json头
if (!(config.data instanceof FormData)) {
config.headers['Content-Type'] = 'application/json;charset=utf-8'
}
// 示例:如果本地有token,放到请求头
// const token = localStorage.getItem('token')
// if(token) config.headers.Authorization = `Bearer ${token}`
return config
},
error => {
return Promise.reject(error)
}
)
// 响应拦截器:拿到后端返回统一处理
service.interceptors.response.use(
response => {
// 直接返回data,组件不用每次写 resp.data
return response.data
},
error => {
// 统一错误处理:打印错误、弹窗提示等
console.error('请求异常:', error)
// http状态码判断
if (error.response) {
switch (error.response.status) {
case 401:
console.log('未授权,请登录')
break
case 404:
console.log('接口地址不存在')
break
case 500:
console.log('服务器内部错误')
break
}
}
return Promise.reject(error)
}
)
export default service