系统特性
🛡️ 三个"0"承诺
request-guard 的设计目标是成为项目里零负担的一层守护:
- 0 侵入 — 业务代码无需改动,接入后所有匹配规则的请求自动受保护
- 0 依赖 — 不绑定任何请求库,axios / fetch / 小程序 / 自定义 SDK 都能接
- 0 风险 — 守护层只做加法不做减法,内置降级保护,永远不会拦住该发的请求
🌐 全平台可用
request-guard 不依赖任何请求库,治理能力的配置写法在所有平台完全一致。区别只在"如何接管请求函数":
| 平台 / 场景 | 推荐接入方式 |
|---|---|
| Web + axios | Axios 安装模式(一键接入) |
| fetch / 自定义 SDK | Wrapper 模式 |
| 微信小程序 | 平台快捷入口 或 Wrapper 模式 |
| React Native | Wrapper 模式 |
| 包体敏感项目 | core 按需入口 + 单能力子路径 |
无论哪种接入方式,rules、defaults、notify、logger 的写法完全一致。同一套治理规则可以跨平台复用。
🧩 能力自由组合
防重、重试、熔断三大内置能力按需引入,同时生效互不冲突:
- 给同一个请求同时配 ignore 防重 + 重试 + 熔断,guard 自动协调
- 多能力组合时,默认
excludeMethods互补设计避免冲突(写操作去重、读操作重试) - 包体敏感项目可只引一个能力,按需装配
// 三种能力同时生效,互不打架
await axios.post('/api/payment/create', data, {
requestGuard: {
duplicate: { strategy: 'ignore' }, // 防重:重复提交静默忽略
retry: { attempts: 2 }, // 重试:失败自动重试 1 次
circuitBreaker: { failCount: 3 } // 熔断:连续失败 3 次后熔断保护
}
});详见 组合配置。
📐 声明式规则
用 rules 声明"哪些请求需要什么治理",业务代码零改动:
- 支持 URL 字符串 / 正则 / 数组 / 函数匹配
- 支持 method / methods 匹配
- 支持完全自定义的函数式规则
- 按声明顺序首个命中生效,前置规则精确覆盖、后置规则兜底
rules: [
{ method: 'post', duplicate: true },
{ url: /\/api\/(list|search)/, duplicate: { strategy: 'reuse' } },
(config) => config.url.includes('payment')
? { circuitBreaker: { failCount: 3 } }
: null
]详见 规则系统。
⚙️ 三级配置优先级
请求级配置(最高) > 规则匹配 > 全局默认(最低)- 全局默认放项目通用参数
- 规则匹配按 URL / 方法批量声明治理策略
- 请求级
requestGuard给单个请求特殊处理,优先级最高,不受excludeMethods限制 - 任何时候
requestGuard: false可完全绕过守护层
详见 配置优先级。
📢 统一观测出口
一个 notify 出口接业务 Toast,一个 logger 出口接开发日志:
| 出口 | 作用 | 触发来源 |
|---|---|---|
notify | UI 提示(toast / message) | duplicate 命中、熔断拦截、熔断状态变更 |
logger | 诊断日志(开发环境 console) | 所有治理行为 + 守护层自身异常 |
notify异步触发,不阻塞请求链路;自身异常被隔离,不影响请求结果logger支持等级过滤、环境感知(devOnly)、自定义实现(继承RequestGuardLogger)- 完整事件目录见 事件与 payload 参考
setupRequestGuard(axios, {
notify: (payload) => Toast.show(payload.message),
logger: new ConsoleRequestGuardLogger({ devOnly: true })
});详见 消息与日志系统。
⛑️ 智能降级
你可能会担心:加了这层东西,万一它自己出 bug 了怎么办?
完全不用担心。request-guard 内置三层降级保护:
- 全链路兜底 — 内部任何环节异常(key 生成、策略判断、notify、logger 等)都被 catch 住,不会向业务代码抛出
- 异常自动放行 — 守护层出问题时,请求直接正常发出,跟没装一样
- 请求级开关 — 任何时候给请求加上
requestGuard: false,就能完全绕过守护层
一句话总结
守护层只做加法,不做减法。它只会帮你拦住不该发的请求,绝不会拦住该发的请求。
守护层自身异常会通过 requestGuard.internalError logger 事件上报,生产环境只走 logger、不裸打 console,可用于排查守护层自身的 bug。
配置传错了怎么办?
如果你不小心把配置项写错了(比如 hashAlgorithm 拼成 'hosh'、strategy 写成 'blok'),guard 不会报错中断请求,而是静默降级为默认值继续工作:
- 开发环境会在控制台输出一条告警,帮你定位拼写问题
- 生产环境保持静默,请求正常走默认参数
这意味着即使配置有笔误,守护层依然能运行,不会因为一个拼写错误导致整个请求链路挂掉。
🔌 完整生命周期管理
守护层支持随时卸载和清理。核心是理解三个函数分别干什么、什么时候该用:
| 函数 | 干什么 | 什么时候用 | 为什么 |
|---|---|---|---|
clearState() | 清空所有能力的运行时状态(在途标记、等待方、熔断单元) | 路由切换、组件销毁、用户登出 | 切页面时上一页的请求状态不该残留到下一页;reuse 等待方挂起不清理会内存泄漏 |
uninstall() | 完全卸载守护层,恢复请求库原始行为 | 退出应用、热更新重装 | 彻底不用 guard 了,或要重新安装新实例前必须先卸载旧的 |
clearRules() | 只清空规则,不动运行时状态 | 临时关闭所有规则匹配 | 只想让后续请求不再匹配规则,但在途请求的状态保留 |
// SPA 路由切换:清空状态,防止上一页的请求残留影响下一页
router.beforeEach(() => {
requestManager.clearState();
});
// 用户登出:先清状态,再卸载守护,彻底恢复
function logout() {
requestManager.clearState();
requestManager.uninstall();
}
// 热更新重装:先卸载旧实例,再重新安装
if (import.meta.hot) {
import.meta.hot.dispose(() => {
requestManager.uninstall();
});
}clearState vs uninstall 的区别
clearState() 像是"清空缓存"——守护还在,后续请求仍受保护,只是把当前状态清掉了。uninstall() 像是"卸载软件"——守护层彻底没了,请求恢复原始行为。路由切换用 clearState,彻底退出用 uninstall。
详见 守护卸载与生命周期。

