一个基于 axios 的请求封装工具 - request-fruge365
🚀 发布了一个基于 axios 的请求封装工具 - request-fruge365
前言
在前端开发中,HTTP 请求是必不可少的功能。虽然 axios 已经很好用了,但在实际项目中,我们经常需要处理 token 管理、重复请求取消、错误统一处理等问题。每个项目都要重复写这些逻辑,既麻烦又容易出错。
于是我封装了一个基于 axios 的请求工具 request-fruge365
,解决了这些痛点,让 HTTP 请求变得更简单、更可靠。
✨ 核心特性
🔄 自动 Token 处理
- 自动从 localStorage/sessionStorage 读取 token
- 支持自定义 token 键名和前缀
- 401 时自动清除 token 并执行回调
🚫 重复请求取消
- 自动识别相同请求(基于 method + url)
- 取消前一个未完成的请求,避免重复提交
- 支持单独禁用某个请求的取消功能
🛡️ 完整错误处理
- 完整的 HTTP 状态码映射(400-504)
- 业务状态码处理,支持多个成功状态码
- 网络错误、超时错误统一处理
- 可选的控制台日志输出
⚙️ 灵活配置
- 支持实例级和请求级配置
- 动态传入参数,请求级配置会覆盖实例级
- 支持多场景适配(Web、小程序、Node.js)
📝 TypeScript 支持
- 完整的类型定义
- 良好的开发体验和代码提示
🚀 快速开始
安装
npm install request-fruge365
基础使用
import request from 'request-fruge365';// GET 请求
const users = await request({url: '/api/users',method: 'get',params: { page: 1, size: 10 }
});// POST 请求
const result = await request({url: '/api/users',method: 'post',data: { name: 'test', age: 25 }
});
自定义配置
import { createRequest } from 'request-fruge365';const api = createRequest({proxyURL: 'https://api.example.com',timeout: 10000,enableLog: true,tokenKey: 'access_token',tokenPrefix: 'Bearer',onUnauthorized: () => {window.location.href = '/login';}
});
🔧 实际应用场景
场景一:处理不同的业务状态码
不同的后端 API 可能返回不同的成功状态码,有些返回 code: 200
,有些返回 code: 0
,还有些返回 code: 'success'
。
// 支持单个状态码
const result1 = await request({url: '/api/third-party',method: 'get',successCode: 0
});// 支持多个状态码
const result2 = await request({url: '/api/legacy-system',method: 'get',successCode: [0, 200, 'success']
});
场景二:文件上传下载
// 文件上传
const formData = new FormData();
formData.append('file', file);const uploadResult = await request({url: '/api/upload',method: 'post',data: formData,headers: {'Content-Type': 'multipart/form-data'},onUploadProgress: (progressEvent) => {const percent = Math.round((progressEvent.loaded * 100) / progressEvent.total);console.log(`上传进度: ${percent}%`);}
});// 文件下载
const downloadResult = await request({url: '/api/download/file.pdf',method: 'get',responseType: 'blob',onDownloadProgress: (progressEvent) => {const percent = Math.round((progressEvent.loaded * 100) / progressEvent.total);console.log(`下载进度: ${percent}%`);}
});
场景三:防重复提交
在表单提交时,用户可能会多次点击提交按钮,导致重复请求。
// 默认启用重复请求取消
const submitResult = await request({url: '/api/submit-form',method: 'post',data: formData
});// 对于轮询接口,可以禁用取消功能
const pollingResult = await request({url: '/api/polling',method: 'get',enableCancel: false
});
📁 API 文件封装最佳实践
在实际项目中,推荐创建统一的 API 文件来管理所有接口:
// api/index.js
import { createRequest } from 'request-fruge365';const request = createRequest({proxyURL: process.env.VUE_APP_API_URL || '/api',enableLog: process.env.NODE_ENV === 'development',timeout: 10000,onUnauthorized: () => {window.location.href = '/login';}
});// 用户管理 API
export const userApi = {getUserList(query) {return request({url: '/users',method: 'get',params: query});},createUser(data) {return request({url: '/users',method: 'post',data});},updateUser(id, data) {return request({url: `/users/${id}`,method: 'put',data});},deleteUser(id) {return request({url: `/users/${id}`,method: 'delete'});}
};
在组件中使用:
import { userApi } from '@/api';export default {async mounted() {const users = await userApi.getUserList({ page: 1, size: 10 });console.log(users);},methods: {async handleCreate(formData) {try {await userApi.createUser(formData);this.$message.success('创建成功');} catch (error) {this.$message.error('创建失败');}}}
};
🌟 不同环境配置
开发环境 vs 生产环境
// 开发环境
const devApi = createRequest({proxyURL: 'http://localhost:3000/api',enableLog: true, // 开启日志timeout: 10000
});// 生产环境
const prodApi = createRequest({proxyURL: 'https://api.prod.com',enableLog: false, // 关闭日志timeout: 5000,onUnauthorized: () => {window.location.href = '/login';}
});
微信小程序适配
const wxApi = createRequest({proxyURL: 'https://api.weixin.com',tokenKey: 'wx_token',tokenPrefix: 'WX-Token',successCode: 0, // 微信 API 通常返回 0 表示成功onUnauthorized: () => {wx.navigateTo({ url: '/pages/login/login' });}
});
🔍 技术实现细节
重复请求取消机制
使用 axios 的 CancelToken 实现:
// 基于 method + url 生成唯一键
const requestKey = `${config.method}_${config.url}`;// 如果存在相同请求,取消前一个
if (cancelTokens[requestKey]) {cancelTokens[requestKey].cancel('重复请求被取消');delete cancelTokens[requestKey];
}// 为当前请求创建新的 CancelToken
cancelTokens[requestKey] = axios.CancelToken.source();
config.cancelToken = cancelTokens[requestKey].token;
多状态码支持
// 支持数组形式的多个成功状态码
if (Array.isArray(currentSuccessCode)) {isSuccess = currentSuccessCode.includes(data.code);
} else {isSuccess = data.code === currentSuccessCode;
}
双模块格式支持
为了兼容不同的项目环境,同时提供 ESM 和 CommonJS 两种格式:
{"main": "lib/index.cjs.js", // CommonJS 入口"module": "index.js", // ESM 入口"types": "index.d.ts", // TypeScript 类型"exports": {".": {"import": "./index.js","require": "./lib/index.cjs.js","types": "./index.d.ts"}}
}
📊 与其他方案对比
特性 | request-fruge365 | 原生 axios | 其他封装 |
---|---|---|---|
自动 token 处理 | ✅ | ❌ | 部分支持 |
重复请求取消 | ✅ | 需手动实现 | 部分支持 |
多状态码支持 | ✅ | ❌ | ❌ |
TypeScript 支持 | ✅ | ✅ | 部分支持 |
配置灵活性 | ✅ | ✅ | 一般 |
学习成本 | 低 | 中 | 中 |
🎯 未来规划
- 请求缓存机制 - 支持 GET 请求缓存,避免重复请求相同数据
- 请求重试机制 - 网络异常时自动重试
- 请求队列管理 - 控制并发请求数量
- 更多适配器 - 支持更多平台(React Native、Electron 等)
📝 总结
request-fruge365
是一个轻量级但功能强大的 HTTP 请求工具,它解决了日常开发中的常见痛点:
- 开箱即用:无需复杂配置,安装即可使用
- 功能完整:token 管理、重复请求取消、错误处理一应俱全
- 高度灵活:支持各种自定义配置,适应不同项目需求
- 类型安全:完整的 TypeScript 支持
- 生产就绪:经过实际项目验证,稳定可靠
如果你也在为 HTTP 请求的各种问题而烦恼,不妨试试这个工具。相信它能让你的开发体验更加愉快!
🔗 相关链接
- GitHub 仓库:https://github.com/fruge365/request
- NPM 包:https://www.npmjs.com/package/request-fruge365
- 在线文档:查看 GitHub README
如果这个工具对你有帮助,欢迎给个 ⭐ Star 支持一下!也欢迎提 Issue 和 PR,一起让它变得更好!