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

axios封装对比

现axios封装

import axios from 'axios';// 当前环境语言选项
const language = window.localStorage.getItem('language-option')?.replace(/"/g, '');// 向全局添加下载进度
const addDownloadProgress = (progressEvent) => {if (progressEvent.lengthComputable) {window.isFileDownloading = progressEvent.loaded !== progressEvent.total;} else {window.isFileDownloading = false;}
};axios.defaults.timeout = 100000;
axios.defaults.withCredentials = true;const axiosInstance = axios.create({baseURL: '',
});axiosInstance.interceptors.request.use((config) => {config.headers.Feign = 'feign';const csrftoken = localStorage.getItem('csrftoken');if (csrftoken) {config.headers.forgerydefense = csrftoken.replace(/"/g, '');}config.headers['language-option'] = language || 'zh-CN';config.headers['logName'] = localStorage.getItem('userid');if (config.method === 'get' && config.params) {const tmpParams = {};for (const key in config.params) {if (config.params[key] === undefined) continue;if (config.params[key] instanceof Array) {tmpParams[key] = config.params[key];} else {tmpParams[key] = encodeURIComponent(config.params[key]);}}config.params = tmpParams;}return config;},(error) => Promise.reject(error)
);axiosInstance.interceptors.response.use((response) => (response.status === 200 ? response : response),(error) => {const { response } = error;return response ? Promise.reject(response.data) : Promise.reject(error);}
);const request = (config) => {const conf = config;if (conf.responseType === 'blob') {if (!conf['onDownloadProgress']) {conf['onDownloadProgress'] = addDownloadProgress;}}return new Promise((resolve) => {axiosInstance.request(conf).then((res) => {resolve(res.data instanceof Blob ? res : res.data);});});
};export function get(config) {return request({ ...config, method: 'GET' });
}export function post(config) {return request({ ...config, method: 'POST' });
}export default request;

Axios封装分析报告

  1. 优点分析
    基础配置合理
axios.defaults.timeout = 100000;        // 100秒超时,适合大文件下载
axios.defaults.withCredentials = true;  // 支持跨域携带cookie

请求拦截器功能完善

axiosInstance.interceptors.request.use((config) => {// 添加Feign标识config.headers.Feign = 'feign';// CSRF防护const csrftoken = localStorage.getItem('csrftoken');if (csrftoken) {config.headers.forgerydefense = csrftoken.replace(/"/g, '');}// 国际化支持config.headers['language-option'] = language || 'zh-CN';// 用户标识config.headers['logName'] = localStorage.getItem('userid');// GET参数编码处理if (config.method === 'get' && config.params) {// 处理undefined值和数组}return config;
});

下载进度支持

const addDownloadProgress = (progressEvent) => {if (progressEvent.lengthComputable) {window.isFileDownloading = progressEvent.loaded !== progressEvent.total;}
};
  1. 存在的问题
    严重问题
  2. 响应拦截器过于简单
axiosInstance.interceptors.response.use((response) => (response.status === 200 ? response : response), // 逻辑冗余(error) => {const { response } = error;return response ? Promise.reject(response.data) : Promise.reject(error);}
);

问题:
没有统一的错误处理
没有统一的成功响应格式处理
没有网络错误、超时等特殊情况的处理
2. 请求函数设计不合理

const request = (config) => {// ...return new Promise((resolve) => {  // 只resolve,不rejectaxiosInstance.request(conf).then((res) => {resolve(res.data instanceof Blob ? res : res.data);});});
};

问题:
使用Promise包装axios,但只处理resolve,不处理reject
错误处理不完整
可能导致Promise永远pending
3. 参数编码逻辑有缺陷

if (config.method === 'get' && config.params) {const tmpParams = {};for (const key in config.params) {if (config.params[key] === undefined) continue;if (config.params[key] instanceof Array) {tmpParams[key] = config.params[key];} else {tmpParams[key] = encodeURIComponent(config.params[key]); // 可能导致双重编码}}config.params = tmpParams;
}

问题:
可能导致双重URL编码
数组处理不完整
没有处理null值
3. 改进建议

  1. 完善响应拦截器
axiosInstance.interceptors.response.use((response) => {// 统一处理成功响应if (response.status === 200) {return response.data;}return Promise.reject(new Error(`HTTP ${response.status}`));},(error) => {// 统一错误处理if (error.response) {// 服务器返回错误状态码const { status, data } = error.response;switch (status) {case 401:// 处理未授权break;case 403:// 处理禁止访问break;case 404:// 处理资源不存在break;case 500:// 处理服务器错误break;}return Promise.reject(data);} else if (error.request) {// 网络错误return Promise.reject(new Error('网络连接失败'));} else {// 其他错误return Promise.reject(error);}}
);
  1. 重构请求函数
const request = async (config) => {const conf = config;// 处理下载进度if (conf.responseType === 'blob') {if (!conf['onDownloadProgress']) {conf['onDownloadProgress'] = addDownloadProgress;}}try {const response = await axiosInstance.request(conf);return response.data instanceof Blob ? response : response.data;} catch (error) {// 统一错误处理throw error;}
};
  1. 优化参数处理
const request = async (config) => {const conf = config;// 处理下载进度if (conf.responseType === 'blob') {if (!conf['onDownloadProgress']) {conf['onDownloadProgress'] = addDownloadProgress;}}try {const response = await axiosInstance.request(conf);return response.data instanceof Blob ? response : response.data;} catch (error) {// 统一错误处理throw error;}
};
  1. 添加请求重试机制
const requestWithRetry = async (config, retries = 3) => {try {return await request(config);} catch (error) {if (retries > 0 && shouldRetry(error)) {await delay(1000);return requestWithRetry(config, retries - 1);}throw error;}
};
  1. 总体评价
    评分:6/10
    优点:
    基础配置合理
    请求拦截器功能较完善
    支持下载进度
    有CSRF防护和国际化支持
    缺点:
    响应拦截器过于简单
    错误处理不完整
    请求函数设计有缺陷
    参数处理逻辑有问题
    缺少重试机制
    缺少请求/响应日志
    建议:
    完善错误处理机制
    重构请求函数
    优化参数处理逻辑
    添加请求重试功能
    增加请求/响应日志
    添加请求取消功能
    统一响应格式处理
    这个axios封装在基础功能上做得不错,但在错误处理和用户体验方面还有很大改进空间。

加强版本

/*** Axios HTTP请求封装* 提供统一的请求处理、错误处理、重试机制、缓存等功能*** @version 2.0.0* @description 增强版HTTP请求封装,支持请求重试、缓存、取消、进度监控等功能*/import axios from 'axios';// ==================== 配置常量 ====================
const CONFIG = {// 请求配置TIMEOUT: 100000, // 默认超时时间(ms)RETRY_TIMES: 3, // 默认重试次数RETRY_DELAY: 1000, // 重试延迟时间(ms)CACHE_EXPIRE: 5 * 60 * 1000, // 缓存过期时间(ms)// 状态码SUCCESS_CODE: 200, // 成功状态码UNAUTHORIZED: 401, // 未授权FORBIDDEN: 403, // 禁止访问NOT_FOUND: 404, // 资源不存在SERVER_ERROR: 500, // 服务器错误// 请求头HEADERS: {'Content-Type': 'application/json',Feign: 'feign',},
};// ==================== 工具函数 ====================/*** 延迟函数* @param {number} ms - 延迟毫秒数* @returns {Promise} 延迟Promise*/
const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));/*** 生成缓存键* @param {Object} config - 请求配置* @returns {string} 缓存键*/
const generateCacheKey = (config) => {const { url, method, params, data } = config;return `${method}:${url}:${JSON.stringify(params)}:${JSON.stringify(data)}`;
};/*** 判断是否应该重试请求* @param {Error} error - 错误对象* @returns {boolean} 是否应该重试*/
const shouldRetry = (error) => {// 网络错误或超时错误应该重试if (!error.response) return true;// 服务器错误(5xx)应该重试const status = error.response.status;return status >= 500 && status < 600;
};/*** 处理请求参数* @param {Object} params - 原始参数* @returns {Object} 处理后的参数*/
const processParams = (params) => {if (!params || typeof params !== 'object') return params;const processed = {};for (const [key, value] of Object.entries(params)) {// 跳过undefined和null值if (value === undefined || value === null) continue;if (Array.isArray(value)) {processed[key] = value;} else if (typeof value === 'object') {// 对象类型转为JSON字符串processed[key] = JSON.stringify(value);} else {// 其他类型转为字符串processed[key] = String(value);}}return processed;
};// ==================== 缓存管理 ====================/*** 简单的内存缓存实现*/
class RequestCache {constructor() {this.cache = new Map();}/*** 设置缓存* @param {string} key - 缓存键* @param {any} value - 缓存值* @param {number} expire - 过期时间(ms)*/set(key, value, expire = CONFIG.CACHE_EXPIRE) {this.cache.set(key, {value,expire: Date.now() + expire,});}/*** 获取缓存* @param {string} key - 缓存键* @returns {any} 缓存值或null*/get(key) {const item = this.cache.get(key);if (!item) return null;if (Date.now() > item.expire) {this.cache.delete(key);return null;}return item.value;}/*** 清除缓存* @param {string} key - 缓存键(可选,不传则清除所有)*/clear(key) {if (key) {this.cache.delete(key);} else {this.cache.clear();}}
}const requestCache = new RequestCache();// ==================== 请求取消管理 ====================/*** 请求取消管理器*/
class CancelManager {constructor() {this.pendingRequests = new Map();}/*** 添加请求到待处理列表* @param {string} key - 请求标识* @param {Function} cancel - 取消函数*/add(key, cancel) {this.pendingRequests.set(key, cancel);}/*** 移除请求* @param {string} key - 请求标识*/remove(key) {this.pendingRequests.delete(key);}/*** 取消指定请求* @param {string} key - 请求标识*/cancel(key) {const cancel = this.pendingRequests.get(key);if (cancel) {cancel();this.remove(key);}}/*** 取消所有请求*/cancelAll() {this.pendingRequests.forEach((cancel) => cancel());this.pendingRequests.clear();}
}const cancelManager = new CancelManager();// ==================== 全局状态管理 ====================// 当前环境语言选项
const language = window.localStorage.getItem('language-option')?.replace(/"/g, '');// 下载进度管理
const addDownloadProgress = (progressEvent) => {if (progressEvent.lengthComputable) {window.isFileDownloading = progressEvent.loaded !== progressEvent.total;} else {window.isFileDownloading = false;}
};// ==================== Axios实例配置 ====================// 设置全局默认配置
axios.defaults.timeout = CONFIG.TIMEOUT;
axios.defaults.withCredentials = true;// 创建axios实例
const axiosInstance = axios.create({baseURL: '',headers: CONFIG.HEADERS,
});// ==================== 请求拦截器 ====================axiosInstance.interceptors.request.use((config) => {// 生成请求标识const requestKey = `${config.method}:${config.url}:${Date.now()}`;config.requestKey = requestKey;// 添加请求头config.headers.Feign = 'feign';// CSRF防护const csrftoken = localStorage.getItem('csrftoken');if (csrftoken) {config.headers.forgerydefense = csrftoken.replace(/"/g, '');}// 国际化支持config.headers['language-option'] = language || 'zh-CN';// 用户标识config.headers['logName'] = localStorage.getItem('userid');// 处理GET请求参数if (config.method === 'get' && config.params) {config.params = processParams(config.params);}// 处理POST请求数据if (config.method === 'post' && config.data) {config.data = processParams(config.data);}// 添加取消令牌const cancelToken = new axios.CancelToken((cancel) => {cancelManager.add(requestKey, cancel);});config.cancelToken = cancelToken;// 请求日志console.log(`🚀 发起请求: ${config.method?.toUpperCase()} ${config.url}`, {params: config.params,data: config.data,headers: config.headers,});return config;},(error) => {console.error('❌ 请求拦截器错误:', error);return Promise.reject(error);}
);// ==================== 响应拦截器 ====================axiosInstance.interceptors.response.use((response) => {const { config, status, data } = response;// 移除请求标识cancelManager.remove(config.requestKey);// 响应日志console.log(`✅ 请求成功: ${config.method?.toUpperCase()} ${config.url}`, {status,data,});// 处理成功响应if (status === CONFIG.SUCCESS_CODE) {return response;}return Promise.reject(new Error(`HTTP ${status}`));},(error) => {// 移除请求标识if (error.config?.requestKey) {cancelManager.remove(error.config.requestKey);}// 请求被取消if (axios.isCancel(error)) {console.log('🚫 请求被取消:', error.message);return Promise.reject(error);}// 响应错误处理if (error.response) {const { status, data, config } = error.response;console.error(`❌ 请求失败: ${config?.method?.toUpperCase()} ${config?.url}`,{status,data,error: error.message,});// 根据状态码处理不同错误switch (status) {case CONFIG.UNAUTHORIZED:// 未授权,跳转到登录页console.warn('⚠️ 用户未授权,请重新登录');// 可以在这里添加跳转登录的逻辑break;case CONFIG.FORBIDDEN:console.warn('⚠️ 访问被禁止');break;case CONFIG.NOT_FOUND:console.warn('⚠️ 请求的资源不存在');break;case CONFIG.SERVER_ERROR:console.warn('⚠️ 服务器内部错误');break;default:console.warn(`⚠️ 请求失败,状态码: ${status}`);}return Promise.reject(data || error);}// 网络错误if (error.request) {console.error('🌐 网络连接失败:', error.message);return Promise.reject(new Error('网络连接失败,请检查网络设置'));}// 其他错误console.error('❌ 请求配置错误:', error.message);return Promise.reject(error);}
);// ==================== 核心请求函数 ====================/*** 核心请求函数* @param {Object} config - 请求配置* @param {Object} options - 额外选项* @returns {Promise} 请求Promise*/
const request = async (config, options = {}) => {const {retry = CONFIG.RETRY_TIMES, // 重试次数retryDelay = CONFIG.RETRY_DELAY, // 重试延迟cache = false, // 是否启用缓存cacheExpire = CONFIG.CACHE_EXPIRE, // 缓存过期时间showLoading = false, // 是否显示加载状态responseFormat = 'standard', // 响应格式: 'standard' | 'direct' | 'auto'} = options;// 处理下载进度if (config.responseType === 'blob') {if (!config.onDownloadProgress) {config.onDownloadProgress = addDownloadProgress;}}// 缓存处理if (cache && config.method?.toLowerCase() === 'get') {const cacheKey = generateCacheKey(config);const cachedData = requestCache.get(cacheKey);if (cachedData) {console.log('📦 使用缓存数据:', cacheKey);return cachedData;}}// 显示加载状态let loadingInstance = null;if (showLoading) {// 这里可以集成Element UI的loading组件// loadingInstance = this.$loading({ text: loadingText });}try {const response = await axiosInstance.request(config);let result;// 根据响应格式处理数据if (response.data instanceof Blob) {// 文件下载,直接返回responseresult = response;} else if (responseFormat === 'direct') {// 直接返回数据,不处理标准格式result = response.data;} else if (responseFormat === 'auto') {// 自动判断:如果有code字段且为0,按标准格式处理;否则直接返回数据if (response.data &&typeof response.data === 'object' &&'code' in response.data) {if (response.data.code === 0) {result =response.data.data !== undefined? response.data.data: response.data;} else {throw new Error(response.data.message || '请求失败');}} else {// 直接返回数组或对象result = response.data;}} else {// 标准格式处理result = response.data;}// 缓存结果if (cache && config.method?.toLowerCase() === 'get') {const cacheKey = generateCacheKey(config);requestCache.set(cacheKey, result, cacheExpire);}return result;} catch (error) {// 重试逻辑if (retry > 0 && shouldRetry(error)) {console.log(`🔄 请求失败,${retryDelay}ms后重试,剩余重试次数: ${retry - 1}`);await delay(retryDelay);return request(config, { ...options, retry: retry - 1 });}throw error;} finally {// 隐藏加载状态if (loadingInstance) {// loadingInstance.close();}}
};// ==================== 便捷方法 ====================/*** GET请求* @param {Object} config - 请求配置* @param {Object} options - 额外选项* @returns {Promise} 请求Promise*/
export function get(config, options = {}) {return request({ ...config, method: 'GET' }, options);
}/*** POST请求* @param {Object} config - 请求配置* @param {Object} options - 额外选项* @returns {Promise} 请求Promise*/
export function post(config, options = {}) {return request({ ...config, method: 'POST' }, options);
}/*** PUT请求* @param {Object} config - 请求配置* @param {Object} options - 额外选项* @returns {Promise} 请求Promise*/
export function put(config, options = {}) {return request({ ...config, method: 'PUT' }, options);
}/*** DELETE请求* @param {Object} config - 请求配置* @param {Object} options - 额外选项* @returns {Promise} 请求Promise*/
export function del(config, options = {}) {return request({ ...config, method: 'DELETE' }, options);
}/*** 文件上传* @param {Object} config - 请求配置* @param {Object} options - 额外选项* @returns {Promise} 请求Promise*/
export function upload(config, options = {}) {const uploadConfig = {...config,method: 'POST',headers: {'Content-Type': 'multipart/form-data',...config.headers,},};return request(uploadConfig, options);
}/*** 文件下载* @param {Object} config - 请求配置* @param {Object} options - 额外选项* @returns {Promise} 请求Promise*/
export function download(config, options = {}) {const downloadConfig = {...config,responseType: 'blob',onDownloadProgress: addDownloadProgress,};return request(downloadConfig, options);
}// ==================== 工具方法 ====================/*** 取消指定请求* @param {string} key - 请求标识*/
export function cancelRequest(key) {cancelManager.cancel(key);
}/*** 取消所有请求*/
export function cancelAllRequests() {cancelManager.cancelAll();
}/*** 清除缓存* @param {string} key - 缓存键(可选)*/
export function clearCache(key) {requestCache.clear(key);
}/*** 设置请求超时时间* @param {number} timeout - 超时时间(ms)*/
export function setTimeout(timeout) {axiosInstance.defaults.timeout = timeout;
}/*** 设置请求头* @param {Object} headers - 请求头*/
export function setHeaders(headers) {Object.assign(axiosInstance.defaults.headers, headers);
}// ==================== 导出 ====================export default request;// 导出配置常量
export { CONFIG };

A. 智能重试机制

// 自动重试失败的请求
const data = await getUsers('admin', {retry: 3,           // 重试3次retryDelay: 2000,   // 每次间隔2秒
});// 重试条件:网络错误、5xx服务器错误
if (retry > 0 && shouldRetry(error)) {await delay(retryDelay);return request(config, { ...options, retry: retry - 1 });
}

B. 智能缓存系统

// 自动缓存GET请求
const clouds = await getClouds({cache: true,                    // 启用缓存cacheExpire: 10 * 60 * 1000,   // 缓存10分钟
});// 缓存键自动生成
const cacheKey = `${method}:${url}:${JSON.stringify(params)}:${JSON.stringify(data)}`;

C. 多格式响应支持

// 标准格式:{code: 0, data: xxx}
const result = await addSalt(params);// 直接格式:直接返回数据
const data = await getUsers('admin', { responseFormat: 'direct' });// 自动格式:智能判断
const permissions = await getOperations(); // 自动处理权限数组

D. 请求取消功能

// 取消单个请求
import { cancelRequest } from '@/utils/http/axios';
cancelRequest('requestKey');// 取消所有请求
import { cancelAllRequests } from '@/utils/http/axios';
cancelAllRequests();// 组件销毁时自动取消
export default {beforeDestroy() {cancelAllRequests();}
}

E. 文件下载优化

// 专门的下载方法
import { download } from '@/utils/http/axios';const blob = await download({url: '/api/download/file.pdf',method: 'post',data: { fileId: '123' }
}, {retry: 1,retryDelay: 2000,showLoading: true
});
  1. 使用方法详解
    A. 基础使用
import { get, post, put, del } from '@/utils/http/axios';// GET请求
const data = await get({url: '/api/users',params: { page: 1, size: 10 }
});// POST请求
const result = await post({url: '/api/users',data: { name: 'John', age: 30 }
});

B. 高级配置

// 带重试和缓存的请求
const data = await get({url: '/api/config',
}, {retry: 3,                    // 重试3次retryDelay: 1000,            // 重试间隔1秒cache: true,                 // 启用缓存cacheExpire: 5 * 60 * 1000,  // 缓存5分钟responseFormat: 'auto',      // 自动响应格式showLoading: true            // 显示加载状态
});

C. 文件操作

import { upload, download } from '@/utils/http/axios';// 文件上传
const formData = new FormData();
formData.append('file', file);
const result = await upload({url: '/api/upload',data: formData
});// 文件下载
const blob = await download({url: '/api/download',method: 'post',data: { fileId: '123' }
}, {showLoading: true,loadingText: '文件下载中...'
});

D. 错误处理

try {const data = await getUsers('admin');
} catch (error) {if (error.response) {// 服务器错误console.error('服务器错误:', error.response.status);} else if (error.request) {// 网络错误console.error('网络连接失败');} else {// 其他错误console.error('请求配置错误:', error.message);}
}
  1. API层使用示例
    A. 标准业务接口
// service.js
export function addSalt(params, options = {}) {return post({url: `/api/collect-server/v1/cfg/addSalt`,data: params,}, { ...DEFAULT_OPTIONS, ...options }).then(response => handleResponse(response, true));
}// 使用
const result = await addSalt(saltData, {retry: 2,showLoading: true
});

B. 配置类接口

// service.js
export function getClouds(options = {}) {return get({url: `/api/collect-server/v1/cfg/getClouds`,}, { ...DEFAULT_OPTIONS, ...CACHE_OPTIONS, responseFormat: 'auto', ...options });
}// 使用 - 自动缓存,直接返回数组
const clouds = await getClouds();

C. 权限接口

// common-plat.js
export function getOperations(options = {}) {return post({url: `/api/oauth2/v1/perms/user/operations`,data: { operations: permission },}, { ...DEFAULT_OPTIONS, ...CACHE_OPTIONS, responseFormat: 'auto', ...options });
}// 使用 - 自动处理权限数组
const permissions = await getOperations();
  1. 性能优化效果
    A. 缓存优化
// 配置接口自动缓存5分钟
const clouds = await getClouds(); // 第一次请求
const clouds2 = await getClouds(); // 使用缓存,不发送请求

B. 重试优化

// 网络不稳定时自动重试
const data = await getUsers('admin', { retry: 3 });
// 如果第一次失败,会自动重试3次

C. 请求取消

// 避免重复请求和内存泄漏
// 页面切换时自动取消未完成的请求
  1. 总结
    优化后的axios封装提供了:
    ✅ 完整的错误处理 - 网络错误、服务器错误、业务错误
    ✅ 智能重试机制 - 自动重试失败的请求
    ✅ 智能缓存系统 - 自动缓存配置类接口
    ✅ 多格式响应支持 - 标准格式、直接格式、自动格式
    ✅ 请求取消功能 - 避免重复请求和内存泄漏
    ✅ 文件操作优化 - 专门的上传下载方法
    ✅ 详细日志记录 - 便于调试和监控
    ✅ 性能优化 - 缓存、重试、取消等机制
    ✅ 向后兼容 - 现有代码无需修改
    ✅ 易于扩展 - 模块化设计,便于添加新功能
    这个封装大大提升了开发效率和用户体验,是现代Web应用HTTP请求处理的最佳实践!

使用方法
xios封装使用方法大全

  1. 基础HTTP方法使用
    GET请求
import { get } from '@/utils/http/axios';// 简单GET请求
const data = await get({url: '/api/users',params: { page: 1, size: 10 }
});// 带配置的GET请求
const data = await get({url: '/api/config',params: { type: 'system' }
}, {retry: 3,cache: true,cacheExpire: 10 * 60 * 1000
});

POST请求

import { post } from '@/utils/http/axios';// 简单POST请求
const result = await post({url: '/api/users',data: { name: 'John', age: 30 }
});// 带配置的POST请求
const result = await post({url: '/api/users',data: userData
}, {retry: 2,showLoading: true
});

PUT请求

import { put } from '@/utils/http/axios';const result = await put({url: '/api/users/123',data: { name: 'John Updated' }
}, {retry: 1
});

DELETE请求

import { del } from '@/utils/http/axios';const result = await del({url: '/api/users/123'
}, {retry: 1
});
  1. 文件操作使用
    文件上传
import { upload } from '@/utils/http/axios';// 单文件上传
const formData = new FormData();
formData.append('file', file);
const result = await upload({url: '/api/upload',data: formData
}, {showLoading: true
});// 多文件上传
const formData = new FormData();
files.forEach(file => {formData.append('files', file);
});
const result = await upload({url: '/api/upload/multiple',data: formData
});

文件下载

import { download } from '@/utils/http/axios';// 简单下载
const blob = await download({url: '/api/download/file.pdf',method: 'get'
});// 带参数的下载
const blob = await download({url: '/api/download',method: 'post',data: { fileId: '123' }
}, {showLoading: true,retry: 1
});// 下载并保存文件
const blob = await download({url: '/api/download/report.xlsx',method: 'post',data: { reportId: '456' }
});// 创建下载链接
const url = window.URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.download = 'report.xlsx';
link.click();
window.URL.revokeObjectURL(url);
  1. 响应格式使用
    标准格式(默认)
// 返回 {code: 0, data: xxx, message: 'success'}
const result = await post({url: '/api/users',data: userData
}, {responseFormat: 'standard' // 默认值
});if (result.code === 0) {const data = result.data;
}

直接格式

// 直接返回 response.data
const data = await get({url: '/api/config'
}, {responseFormat: 'direct'
});

自动格式(推荐)

// 智能判断:有code字段按标准格式处理,否则直接返回数据
const permissions = await get({url: '/api/permissions'
}, {responseFormat: 'auto'
});// 如果返回 {code: 0, data: [...]} 则自动提取 data
// 如果直接返回 [...] 则直接使用
  1. 缓存使用
    启用缓存
// 自动缓存GET请求
const data = await get({url: '/api/config'
}, {cache: true,cacheExpire: 5 * 60 * 1000 // 缓存5分钟
});// 第二次调用会使用缓存
const cachedData = await get({url: '/api/config'
}, {cache: true
});

清除缓存

import { clearCache } from '@/utils/http/axios';// 清除所有缓存
clearCache();// 清除特定缓存
clearCache('get:/api/config');
  1. 重试机制使用
    基础重试
const data = await get({url: '/api/users'
}, {retry: 3,           // 重试3次retryDelay: 1000    // 每次间隔1秒
});

不同场景的重试配置

// 重要数据,多重重试
const userData = await get({url: '/api/user/profile'
}, {retry: 5,retryDelay: 2000
});// 文件下载,少量重试
const blob = await download({url: '/api/download/file'
}, {retry: 1,retryDelay: 3000
});// 配置数据,不重试
const config = await get({url: '/api/config'
}, {retry: 0,cache: true
});
  1. 请求取消使用
    取消单个请求
import { cancelRequest } from '@/utils/http/axios';// 发起请求
const requestKey = `get:/api/users:${Date.now()}`;
const data = await get({url: '/api/users',requestKey
});// 取消请求
cancelRequest(requestKey);

取消所有请求

import { cancelAllRequests } from '@/utils/http/axios';// 在组件销毁时取消所有请求
export default {beforeDestroy() {cancelAllRequests();}
}// 在页面切换时取消
window.addEventListener('beforeunload', () => {cancelAllRequests();
});
  1. 错误处理使用
    try-catch处理
try {const data = await get({url: '/api/users'});
} catch (error) {if (error.response) {// 服务器错误console.error('服务器错误:', error.response.status);} else if (error.request) {// 网络错误console.error('网络连接失败');} else {// 其他错误console.error('请求配置错误:', error.message);}
}

Promise处理

get({url: '/api/users'
}).then(data => {console.log('成功:', data);
}).catch(error => {console.error('失败:', error);
});
  1. API层使用示例
    业务接口调用
import { getUsers, addSalt, downloadFile } from '@/api/service';// 获取用户列表(带缓存)
const users = await getUsers('admin', false, {cache: true,cacheExpire: 10 * 60 * 1000
});// 添加Salt(带重试)
const result = await addSalt(saltData, {retry: 3,showLoading: true
});// 下载文件(带进度)
const blob = await downloadFile(subTaskId, {showLoading: true
});

权限接口调用

import { getOperations, getUserName } from '@/api/common-plat';// 获取权限(自动格式)
const permissions = await getOperations();// 获取用户名(自动格式)
const username = await getUserName();
  1. 高级配置使用
    自定义配置
// 全局配置
import { setTimeout, setHeaders } from '@/utils/http/axios';// 设置超时时间
setTimeout(30000);// 设置请求头
setHeaders({'Custom-Header': 'value','Authorization': 'Bearer token'
});

组合配置

const advancedOptions = {retry: 3,retryDelay: 2000,cache: true,cacheExpire: 10 * 60 * 1000,responseFormat: 'auto',showLoading: true
};const data = await get({url: '/api/important-data'
}, advancedOptions);
  1. 实际项目使用场景
    页面初始化
export default {async mounted() {try {// 并行加载配置数据const [clouds, permissions, userInfo] = await Promise.all([getClouds({ cache: true }),getOperations({ cache: true }),getUserName({ cache: true })]);this.clouds = clouds;this.permissions = permissions;this.userInfo = userInfo;} catch (error) {this.$message.error('初始化失败');}}
}

表单提交

async submitForm() {try {this.loading = true;const result = await addSalt(this.formData, {retry: 2,showLoading: false // 使用自定义loading});this.$message.success('添加成功');this.$emit('success');} catch (error) {this.$message.error(error.message || '添加失败');} finally {this.loading = false;}
}

文件下载

async downloadReport() {try {const blob = await downloadFile(this.reportId, {showLoading: true});// 保存文件const url = window.URL.createObjectURL(blob);const link = document.createElement('a');link.href = url;link.download = `report_${Date.now()}.xlsx`;link.click();window.URL.revokeObjectURL(url);this.$message.success('下载成功');} catch (error) {this.$message.error('下载失败');}
}
  1. 最佳实践总结
    配置建议
// 配置类接口:启用缓存,不重试
const configOptions = {cache: true,cacheExpire: 5 * 60 * 1000,retry: 0
};// 业务接口:启用重试,不缓存
const businessOptions = {retry: 2,retryDelay: 1000,cache: false
};// 文件操作:少量重试,显示进度
const fileOptions = {retry: 1,retryDelay: 2000,showLoading: true
};

错误处理建议

// 统一错误处理
const handleApiError = (error) => {if (error.response?.status === 401) {// 跳转登录router.push('/login');} else if (error.response?.status === 403) {this.$message.error('权限不足');} else {this.$message.error(error.message || '操作失败');}
};

这些使用方法涵盖了axios封装的所有功能,可以根据具体需求选择合适的配置和调用方式!

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

相关文章:

  • 《C#与.NET Core跨平台开发的融合架构与实践逻辑》
  • 编程语言Java——核心技术篇(六)解剖反射:性能的代价还是灵活性的福音?
  • 【[CSP-J 2022] 上升点列】
  • RabbitMQ 的死信队列完整指南 (With Spring Boot)
  • 从遮挡难题到精准测量:激光频率梳技术如何实现深孔 3D 轮廓的 2um 级重复精度?
  • Mac上优雅简单地使用Git:从入门到高效工作流
  • 05百融云策略引擎项目交付-laravel实战完整交付定义常量分文件配置-独立建立lib类处理-成功导出pdf-优雅草卓伊凡
  • LCM中间件入门(1):工作原理核心概念及Ubuntu环境下的C++实践
  • 【Debian】4-‌2 Gitea搭建
  • Git踩坑
  • windows服务器 maven 配置环境变量,验证maven环境变量是否配置成功
  • es的histogram直方图聚合和terms分组聚合
  • Ubuntu/Debian 搭建 Nginx RTMP 服务器全攻略
  • [Broken IOS] 配置CLI | 终端用户界面TUI
  • 分布式ID方案(标记)
  • 【Linux】linux基础开发工具(二) 编译器gcc/g++、动静态库感性认识、自动化构建-make/Makefile
  • BasicAuthenticationFilter处理 HTTP 基本认证(Basic Authentication)的核心过滤器详解
  • 打破数据质量瓶颈:用n8n实现30秒专业数据质量报告自动化
  • 50天50个小项目 (Vue3 + Tailwindcss V4) ✨ | LiveUserFilter(实时用户过滤组件)
  • ensp安全策略实验
  • 【工具】NVM完全指南:Node.js版本管理工具的安装与使用详解
  • 嵌入式仿真教学的革新力量:深圳航天科技创新研究院引领高效学习新时代
  • 【n8n】如何跟着AI学习n8n【03】:HTTPRequest节点、Webhook节点、SMTP节点、mysql节点
  • 从“碎片化”到“完美重组”:IP报文的分片艺术
  • mysql笔记02:DML插入、更新、删除数据
  • 【读书笔记】Design Patterns (1994)✅
  • 微软发布Microsoft Sentinel数据湖国际版
  • JVM之【Java虚拟机概述】
  • Python实现调整矩阵维度: view
  • 【13】大恒相机SDK C#开发 —— Fom1中实时处理的8个图像 实时显示在Form2界面的 pictureBox中