当前位置: 首页 > news >正文

vue封装请求拦截器 响应拦截器

在 Vue 项目中封装请求拦截器和响应拦截器通常使用 Axios 库。以下是一个完整的封装示例,包含基础配置、拦截器实现和错误处理:

### 第一步:安装 Axios
```bash
npm install axios
```

### 第二步:创建封装文件 `src/utils/request.js`
```javascript
import axios from 'axios'
import { Message } from 'element-ui' // 按需引入 UI 框架提示组件
import router from '@/router' // 引入路由实例

// 创建 axios 实例
const service = axios.create({
baseURL: process.env.VUE_APP_BASE_API, // 从环境变量读取基础 URL
timeout: 10000, // 请求超时时间
headers: { 'Content-Type': 'application/json;charset=UTF-8' }
})

// 请求拦截器
service.interceptors.request.use(
config => {
// 在发送请求之前做些什么(例如添加 token)
const token = localStorage.getItem('token')
if (token) {
config.headers['Authorization'] = `Bearer ${token}`
}

// 可添加全局 loading 控制
// showLoading()

return config
},
error => {
// 对请求错误做些什么
return Promise.reject(error)
}
)

// 响应拦截器
service.interceptors.response.use(
response => {
// 隐藏全局 loading
// hideLoading()

// 处理二进制数据
if (response.config.responseType === 'blob') {
return response.data
}

const res = response.data

// 根据后端约定判断业务状态码
if (res.code !== 200) {
// 处理特殊状态码(如 token 过期)
if (res.code === 401) {
Message.error('登录已过期,请重新登录')
router.push('/login')
return Promise.reject(new Error('未授权'))
}

// 显示错误提示(可配置不显示特定状态码)
if (!response.config.noShowError) {
Message.error(res.message || '请求失败')
}

return Promise.reject(new Error(res.message || 'Error'))
} else {
// 返回核心数据
return res.data
}
},
error => {
// 隐藏全局 loading
// hideLoading()

// 处理 HTTP 状态码错误
if (error.response) {
switch (error.response.status) {
case 400:
error.message = '请求错误'
break
case 401:
error.message = '未授权,请登录'
router.replace('/login')
break
case 403:
error.message = '拒绝访问'
break
case 404:
error.message = `请求地址出错: ${error.response.config.url}`
break
case 500:
error.message = '服务器内部错误'
break
default:
error.message = `连接错误 ${error.response.status}`
}
} else if (error.message.includes('timeout')) {
error.message = '请求超时,请检查网络'
} else {
error.message = '网络连接异常'
}

Message.error(error.message)
return Promise.reject(error)
}
)

/**
* 封装通用请求方法
* @param {Object} config 请求配置
*/
export function request(config) {
return service(config)
}

/**
* 封装 GET 请求
* @param {String} url 
* @param {Object} params 
* @param {Object} options 额外配置 
*/
export function get(url, params = {}, options = {}) {
return service({
url,
method: 'get',
params,
...options
})
}

/**
* 封装 POST 请求
* @param {String} url 
* @param {Object} data 
* @param {Object} options 额外配置
*/
export function post(url, data = {}, options = {}) {
return service({
url,
method: 'post',
data,
...options
})
}

// 导出其他常用方法
export default {
request,
get,
post,
put: (url, data) => service({ url, method: 'put', data }),
delete: url => service({ url, method: 'delete' })
}
```

### 第三步:在 Vue 中全局引入(可选)
`src/main.js`
```javascript
import Vue from 'vue'
import request from '@/utils/request'

Vue.prototype.$http = request // 组件内使用 this.$http.get(...)
```

### 第四步:在组件中使用
```vue
<script>
import { get, post } from '@/utils/request'

export default {
methods: {
// GET 请求示例
async fetchData() {
try {
const res = await get('/api/user/list', {
page: 1,
size: 20
}, {
noShowError: true // 可选:禁止自动显示错误
})
console.log('数据获取成功', res)
} catch (err) {
console.error('请求失败', err)
}
},

    // POST 请求示例
async submitForm() {
const data = { username: 'admin', password: '123456' }
const res = await post('/api/login', data)
console.log('登录结果', res)
},

    // 使用全局注入方式
async deleteItem() {
const res = await this.$http.delete('/api/item/123')
console.log('删除结果', res)
}
}
}
</script>
```

### 关键功能说明:
1. **请求拦截器**:
- 自动添加 JWT 认证 Token
- 统一设置 Content-Type
- 全局 Loading 控制点(需自行实现)

2. **响应拦截器**:
- 处理二进制响应数据
- 统一处理业务错误码(如 401 跳转登录)
- 捕获 HTTP 状态码错误
- 网络异常处理(超时/断网)

3. **灵活配置**:
- `noShowError` 参数:禁止自动错误提示
- 环境变量管理 API 地址
- 支持特殊响应类型(如 blob)

4. **错误处理**:
- 分类处理网络错误/业务错误
- 自动显示友好错误提示
- 401 自动跳转登录页

### 最佳实践建议:
1. **环境配置**:在 `.env.development` 和 `.env.production` 中配置不同的 `VUE_APP_BASE_API`
2. **错误处理**:可在拦截器中添加错误日志上报
3. **重试机制**:可在响应拦截器中添加请求重试逻辑
4. **取消请求**:添加请求取消功能(使用 axios CancelToken)
5. **文件上传**:单独封装上传方法,处理进度事件

通过这种封装方式,可以实现:
- 统一处理认证逻辑
- 减少重复代码
- 集中管理 API 错误
- 增强请求的可控性
- 快速适配后端接口变更

http://www.lryc.cn/news/623735.html

相关文章:

  • SCAI采用公平发射机制成功登陆LetsBonk,60%代币供应量已锁仓
  • 智能合约里的 “拒绝服务“ 攻击:让你的合约变成 “死机的手机“
  • 数学建模 14 中心对数比变换
  • 原子操作及基于原子操作的shared_ptr实现
  • Leaflet赋能:WebGIS视角下的省域区县天气可视化实战攻略
  • 数据结构:二叉搜索树(Binary Search Tree)
  • ansible管理变量和事实
  • 《Python学习之文件操作:从入门到精通》
  • 剑指offer第2版——面试题5:替换空格
  • Java注解学习记录
  • 26. 值传递和引用传递的区别的什么?为什么说Java中只有值传递
  • 大模型对齐算法合集(一)
  • Zemax 中的透镜设计 - 像差理论
  • 评测系统构建
  • 深入分析 Linux PCI Express 子系统
  • 计算机网络 TCP time_wait 状态 详解
  • 10 SQL进阶-SQL优化(8.15)
  • Matlab课程实践——基于MATLAB设计的计算器软件(简单、科学、电工、矩阵及贷款计算)
  • esp32(自定义分区)coredump
  • C语言私人学习笔记分享
  • 关于第一次接触Linux TCP/IP网络相关项目
  • 使用Ansys Fluent进行倒装芯片封装Theta-JA热阻表征
  • 计算机网络 OSI 七层模型和 TCP 五层模型
  • IP 分片和组装的具体过程
  • 数字货币的法律属性与监管完善路径探析
  • Trae 辅助下的 uni-app 跨端小程序工程化开发实践分享
  • 【Java后端】Spring Boot 集成 MyBatis-Plus 全攻略
  • 【昇腾】单张48G Atlas 300I Duo推理卡MindIE+WebUI方式跑14B大语言模型_20250817
  • 前端vue3+后端spring boot导出数据
  • Java 大视界 -- Java 大数据分布式计算在基因测序数据分析与精准医疗中的应用(400)