🚀 发布了一个基于 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,一起让它变得更好!