在前后端分离的开发模式中,Axios 作为一款基于 Promise 的 HTTP 客户端,已成为 Vue 和 React 等主流框架的首选请求工具,在实际项目中,为了统一管理接口地址、请求头、拦截器等公共配置,通常会封装一个 Axios 实例,实现 API 的集中化管理,本文将详细介绍如何配置 Axios 的公用 API,包括基础配置、拦截器设置、错误处理、请求封装及最佳实践,帮助开发者构建高效、可维护的网络请求层。

Axios 基础配置
在配置公用 API 前,首先需要安装 Axios 并创建一个 Axios 实例,通过 axios.create() 方法可以生成一个自定义配置的 Axios 实例,避免全局污染,同时支持多实例复用。
安装与引入
npm install axios # 或 yarn add axios
在项目中创建 utils/request.js 文件,引入 Axios 并初始化实例:
import axios from 'axios';
const service = axios.create({
baseURL: 'https://api.example.com', // 公共接口地址
timeout: 10000, // 请求超时时间
headers: { 'Content-Type': 'application/json' } // 默认请求头
});
核心配置参数
axios.create() 支持的常用配置参数如下表所示:
| 参数名 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| baseURL | string | 公共接口前缀,所有请求地址会自动拼接此前缀 | |
| timeout | number | 0(无超时) | 请求超时时间(毫秒),超过时间请求将中断 |
| headers | object | 设置请求头,如 {'Content-Type': 'application/json'} |
|
| params | object | URL 查询参数,会自动拼接在 URL 后面,如 ?key=value |
|
| data | object | 请求体数据,仅适用于 POST、PUT、PATCH 等请求方法 | |
| withCredentials | boolean | false | 是否携带跨域凭证(如 cookies),需后端配合 Access-Control-Allow-Origin |
请求与响应拦截器
拦截器是 Axios 的核心功能之一,可在请求发送前或响应返回后进行统一处理,例如添加 token、处理错误数据、统一响应格式等。
请求拦截器
在请求拦截器中,可以统一添加 token、修改请求参数、处理重复请求等逻辑:
service.interceptors.request.use(
config => {
// 从 localStorage 获取 token
const token = localStorage.getItem('token');
if (token) {
config.headers['Authorization'] = `Bearer ${token}`;
}
// 避免重复请求(可选)
if (config.cancelToken) {
config.cancelToken.cancel(`重复请求: ${config.url}`);
}
return config;
},
error => {
// 请求配置错误处理
console.error('请求拦截器错误:', error);
return Promise.reject(error);
}
);
响应拦截器
响应拦截器用于统一处理接口返回数据,例如解析响应体、处理错误码、转换数据格式等:
service.interceptors.response.use(
response => {
const { data, code, message } = response.data;
// 假设后端返回格式为 { code: 200, data: {}, message: 'success' }
if (code === 200) {
return data; // 只返回业务数据
} else {
// 业务错误处理
ElMessage.error(message || '请求失败');
return Promise.reject(new Error(message));
}
},
error => {
// HTTP 状态码错误处理
if (error.response) {
const { status, data } = error.response;
switch (status) {
case 401:
// token 失效,跳转登录页
router.push('/login');
break;
case 403:
ElMessage.error('无权限访问');
break;
case 404:
ElMessage.error('请求资源不存在');
break;
case 500:
ElMessage.error('服务器错误');
break;
default:
ElMessage.error(data.message || '网络错误');
}
} else if (error.request) {
// 请求已发送但无响应
ElMessage.error('网络连接失败,请检查网络');
} else {
// 请求配置错误
ElMessage.error('请求失败: ' + error.message);
}
return Promise.reject(error);
}
);
拦截器执行流程
请求拦截器与响应拦截器的执行顺序如下:

- 请求阶段:请求拦截器(1)→ 请求拦截器(2)→ … → 发送请求
- 响应阶段:响应拦截器(1)→ 响应拦截器(2)→ … → 返回结果
API 接口封装
为了方便调用,可将不同模块的接口封装成独立的方法,统一管理在 api 目录下,创建 api/user.js 和 api/product.js:
用户模块接口
import request from '@/utils/request';
// 用户登录
export function login(data) {
return request({
url: '/user/login',
method: 'post',
data
});
}
// 获取用户信息
export function getUserInfo() {
return request({
url: '/user/info',
method: 'get'
});
}
产品模块接口
import request from '@/utils/request';
// 获取产品列表
export function getProductList(params) {
return request({
url: '/product/list',
method: 'get',
params
});
}
// 添加产品
export function addProduct(data) {
return request({
url: '/product/add',
method: 'post',
data
});
}
接口调用示例
在组件或服务中直接调用封装好的接口:
import { login, getUserInfo } from '@/api/user';
// 登录
const handleLogin = async (form) => {
try {
const result = await login(form);
console.log('登录成功:', result);
} catch (error) {
console.error('登录失败:', error);
}
};
// 获取用户信息
const fetchUserInfo = async () => {
try {
const userInfo = await getUserInfo();
console.log('用户信息:', userInfo);
} catch (error) {
console.error('获取用户信息失败:', error);
}
};
高级配置与最佳实践
取消重复请求
通过 Axios 的 CancelToken 可以取消未完成的请求,避免重复请求导致的数据问题:
// 在 request.js 中添加
const pendingRequests = new Map();
service.interceptors.request.use(config => {
const requestKey = `${config.url}_${JSON.stringify(config.params)}`;
if (pendingRequests.has(requestKey)) {
const cancel = pendingRequests.get(requestKey);
cancel('重复请求已取消');
}
config.cancelToken = new axios.CancelToken(cancel => {
pendingRequests.set(requestKey, cancel);
});
return config;
});
service.interceptors.response.use(
response => {
const requestKey = `${response.config.url}_${JSON.stringify(response.config.params)}`;
pendingRequests.delete(requestKey);
return response;
},
error => {
if (axios.isCancel(error)) {
console.log('请求已取消:', error.message);
} else {
const requestKey = `${error.config.url}_${JSON.stringify(error.config.params)}`;
pendingRequests.delete(requestKey);
}
return Promise.reject(error);
}
);
环境变量配置
通过 .env 文件管理不同环境的接口地址,实现开发、测试、生产环境的切换:
# .env.development VUE_APP_API_BASE_URL=https://dev-api.example.com # .env.production VUE_APP_API_BASE_URL=https://prod-api.example.com
修改 request.js 中的 baseURL:
const service = axios.create({
baseURL: process.env.VUE_APP_API_BASE_URL,
// 其他配置...
});
请求重试机制
对于因网络波动导致的请求失败,可配置自动重试逻辑:
service.interceptors.response.use(
response => response,
async error => {
const config = error.config;
if (!config || !config.retry) return Promise.reject(error);
config.retryCount = config.retryCount || 0;
if (config.retryCount >= config.retry) return Promise.reject(error);
config.retryCount += 1;
await new Promise(resolve => setTimeout(resolve, 1000)); // 延迟 1 秒重试
return service(config);
}
);
// 调用时配置重试次数
export function getData() {
return request({
url: '/data',
retry: 3 // 最多重试 3 次
});
}
相关问答 FAQs
问题 1:如何处理跨域问题?
答:跨域问题需前后端配合解决,前端可通过 proxy 代理接口地址(开发环境),在 vue.config.js 中配置:

module.exports = {
devServer: {
proxy: {
'/api': {
target: 'https://api.example.com',
changeOrigin: true,
pathRewrite: { '^/api': '' }
}
}
}
};
生产环境需后端设置响应头 Access-Control-Allow-Origin,并配置 withCredentials: true 以支持跨域携带凭证。
问题 2:如何统一处理全局错误?
答:在响应拦截器的 error 回调中,可根据 HTTP 状态码或业务错误码进行统一处理,封装一个 handleError 方法:
function handleError(error) {
if (error.response) {
const { status } = error.response;
const errorMsg = {
400: '请求参数错误',
401: '未授权,请登录',
403: '拒绝访问',
404: '请求资源不存在',
500: '服务器内部错误'
}[status] || '网络错误';
ElMessage.error(errorMsg);
} else {
ElMessage.error('网络连接失败');
}
}
然后在响应拦截器中调用该方法,实现全局错误提示。
通过以上配置与封装,Axios 的公用 API 能够实现请求的统一管理,提升代码的可维护性和复用性,开发者可根据项目需求进一步扩展功能,如请求缓存、上传进度、Mock 数据等,构建更完善的网络请求层。
原创文章,发布者:酷番叔,转转请注明出处:https://cloud.kd.cn/ask/70489.html