python
import axios from "axios";
import { ElMessage } from "element-plus";
import store from "@/store";
import router from "@/router";
// 创建axios实例
const service = axios.create({
baseURL: "http://localhost:8080/api", // 后端地址
timeout: 5000,
});
// 请求拦截器
service.interceptors.request.use(
(config) => {
// 如果有token,添加到请求头
if (store.getters.token) {
config.headers["Authorization"] = "Bearer " + store.getters.token;
}
return config;
},
(error) => {
console.log(error);
return Promise.reject(error);
}
);
// 响应拦截器
service.interceptors.response.use(
(response) => {
// 如果是blob类型的响应(文件下载),直接返回
if (response.config.responseType === 'blob') {
return response.data;
}
// 如果响应的Content-Type是text/csv,也直接返回
const contentType = response.headers['content-type'];
if (contentType && contentType.includes('text/csv')) {
return response.data;
}
const res = response.data;
// 如果code不是200,说明出错了
if (res.code !== 200) {
ElMessage({
message: res.message || "请求失败",
type: "error",
duration: 5 * 1000,
});
// 401: 未登录
if (res.code === 401) {
store.dispatch("user/logout");
router.push("/login");
}
return Promise.reject(new Error(res.message || "请求失败"));
} else {
return res;
}
},
(error) => {
console.log("err" + error);
ElMessage({
message: error.message,
type: "error",
duration: 5 * 1000,
});
return Promise.reject(error);
}
);
export default service;
基于 Axios 的 HTTP 请求封装文件,提供了完整的请求/响应拦截、错误处理和认证机制。
1. 依赖导入
javascript
import axios from "axios";
import { ElMessage } from "element-plus";
import store from "@/store";
import router from "@/router";
axios
:HTTP 请求库ElMessage
:ElementPlus 的消息提示组件store
:Vuex 状态管理器,用于获取用户 tokenrouter
:Vue Router,用于页面跳转(如登录失效时跳转到登录页)
2. 创建 Axios 实例
javascript
const service = axios.create({
baseURL: "http://localhost:8080/api", // 后端地址
timeout: 5000,
});
- baseURL:设置基础 URL,所有请求都会以此为前缀
- timeout:请求超时时间 5 秒,避免请求长时间挂起
3. 请求拦截器
javascript
service.interceptors.request.use(
(config) => {
// 如果有token,添加到请求头
if (store.getters.token) {
config.headers["Authorization"] = "Bearer " + store.getters.token;
}
return config;
},
(error) => {
console.log(error);
return Promise.reject(error);
}
);
功能说明:
- 自动添加认证头:检查 store 中是否有 token,如果有则自动添加到请求头
- Bearer Token 格式:使用标准的 JWT Token 认证格式
- 错误处理:捕获请求配置阶段的错误
4. 响应拦截器
这是代码的核心部分,处理各种响应情况:
4.1 特殊响应类型处理
javascript
// 如果是blob类型的响应(文件下载),直接返回
if (response.config.responseType === 'blob') {
return response.data;
}
// 如果响应的Content-Type是text/csv,也直接返回
const contentType = response.headers['content-type'];
if (contentType && contentType.includes('text/csv')) {
return response.data;
}
- 文件下载处理:对于 blob 类型响应(通常是文件下载),直接返回数据
- CSV 文件处理:对于 CSV 格式的响应,也直接返回原始数据
- 避免数据结构解析:这些特殊类型不需要按照标准 API 响应格式处理
4.2 标准 API 响应处理
javascript
const res = response.data;
// 如果code不是200,说明出错了
if (res.code !== 200) {
ElMessage({
message: res.message || "请求失败",
type: "error",
duration: 5 * 1000,
});
// 401: 未登录
if (res.code === 401) {
store.dispatch("user/logout");
router.push("/login");
}
return Promise.reject(new Error(res.message || "请求失败"));
} else {
return res;
}
处理逻辑:
- 统一响应格式 :假设后端返回格式为
{ code: number, message: string, data: any }
- 错误状态处理:code 不为 200 时视为错误
- 用户提示:使用 ElMessage 显示错误信息
- 认证失效处理 :
- 401 状态码表示未登录或 token 过期
- 自动执行登出操作(清除 store 中的用户信息)
- 跳转到登录页面
- 错误传播:返回 rejected Promise,便于上层捕获处理
4.3 网络错误处理
javascript
(error) => {
console.log("err" + error);
ElMessage({
message: error.message,
type: "error",
duration: 5 * 1000,
});
return Promise.reject(error);
}
- 网络异常:处理网络连接失败、超时等错误
- 用户反馈:显示错误消息给用户
- 错误日志:在控制台记录错误信息
5. 设计模式和最佳实践
5.1 拦截器模式
- 请求拦截:统一添加认证信息
- 响应拦截:统一处理错误和特殊情况
5.2 错误处理策略
- 分层错误处理:网络错误、业务错误分别处理
- 用户友好:所有错误都有用户提示
- 自动化处理:认证失效自动跳转登录
5.3 代码复用
- 全局配置:一次配置,整个项目复用
- 统一格式:所有 HTTP 请求使用相同的处理逻辑
6. 使用示例
javascript
// 在组件中使用
import request from '@/utils/request'
// GET 请求
request.get('/users')
// POST 请求
request.post('/users', { name: 'John' })
// 文件下载
request.get('/export/csv', { responseType: 'blob' })