Skip to content

系统特性

🛡️ 三个"0"承诺

request-guard 的设计目标是成为项目里零负担的一层守护:

  • 0 侵入 — 业务代码无需改动,接入后所有匹配规则的请求自动受保护
  • 0 依赖 — 不绑定任何请求库,axios / fetch / 小程序 / 自定义 SDK 都能接
  • 0 风险 — 守护层只做加法不做减法,内置降级保护,永远不会拦住该发的请求

🌐 全平台可用

request-guard 不依赖任何请求库,治理能力的配置写法在所有平台完全一致。区别只在"如何接管请求函数":

平台 / 场景推荐接入方式
Web + axiosAxios 安装模式(一键接入)
fetch / 自定义 SDKWrapper 模式
微信小程序平台快捷入口 或 Wrapper 模式
React NativeWrapper 模式
包体敏感项目core 按需入口 + 单能力子路径

无论哪种接入方式,rulesdefaultsnotifylogger 的写法完全一致。同一套治理规则可以跨平台复用。

🧩 能力自由组合

防重、重试、熔断三大内置能力按需引入,同时生效互不冲突

  • 给同一个请求同时配 ignore 防重 + 重试 + 熔断,guard 自动协调
  • 多能力组合时,默认 excludeMethods 互补设计避免冲突(写操作去重、读操作重试)
  • 包体敏感项目可只引一个能力,按需装配
javascript
// 三种能力同时生效,互不打架
await axios.post('/api/payment/create', data, {
  requestGuard: {
    duplicate: { strategy: 'ignore' },    // 防重:重复提交静默忽略
    retry: { attempts: 2 },               // 重试:失败自动重试 1 次
    circuitBreaker: { failCount: 3 }      // 熔断:连续失败 3 次后熔断保护
  }
});

详见 组合配置

📐 声明式规则

rules 声明"哪些请求需要什么治理",业务代码零改动:

  • 支持 URL 字符串 / 正则 / 数组 / 函数匹配
  • 支持 method / methods 匹配
  • 支持完全自定义的函数式规则
  • 按声明顺序首个命中生效,前置规则精确覆盖、后置规则兜底
javascript
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 出口接开发日志:

出口作用触发来源
notifyUI 提示(toast / message)duplicate 命中、熔断拦截、熔断状态变更
logger诊断日志(开发环境 console)所有治理行为 + 守护层自身异常
  • notify 异步触发,不阻塞请求链路;自身异常被隔离,不影响请求结果
  • logger 支持等级过滤、环境感知(devOnly)、自定义实现(继承 RequestGuardLogger
  • 完整事件目录见 事件与 payload 参考
javascript
setupRequestGuard(axios, {
  notify: (payload) => Toast.show(payload.message),
  logger: new ConsoleRequestGuardLogger({ devOnly: true })
});

详见 消息与日志系统

⛑️ 智能降级

你可能会担心:加了这层东西,万一它自己出 bug 了怎么办?

完全不用担心。request-guard 内置三层降级保护:

  1. 全链路兜底 — 内部任何环节异常(key 生成、策略判断、notify、logger 等)都被 catch 住,不会向业务代码抛出
  2. 异常自动放行 — 守护层出问题时,请求直接正常发出,跟没装一样
  3. 请求级开关 — 任何时候给请求加上 requestGuard: false,就能完全绕过守护层

一句话总结

守护层只做加法,不做减法。它只会帮你拦住不该发的请求,绝不会拦住该发的请求。

守护层自身异常会通过 requestGuard.internalError logger 事件上报,生产环境只走 logger、不裸打 console,可用于排查守护层自身的 bug。

配置传错了怎么办?

如果你不小心把配置项写错了(比如 hashAlgorithm 拼成 'hosh'strategy 写成 'blok'),guard 不会报错中断请求,而是静默降级为默认值继续工作:

  • 开发环境会在控制台输出一条告警,帮你定位拼写问题
  • 生产环境保持静默,请求正常走默认参数

这意味着即使配置有笔误,守护层依然能运行,不会因为一个拼写错误导致整个请求链路挂掉。

🔌 完整生命周期管理

守护层支持随时卸载和清理。核心是理解三个函数分别干什么、什么时候该用:

函数干什么什么时候用为什么
clearState()清空所有能力的运行时状态(在途标记、等待方、熔断单元)路由切换、组件销毁、用户登出切页面时上一页的请求状态不该残留到下一页;reuse 等待方挂起不清理会内存泄漏
uninstall()完全卸载守护层,恢复请求库原始行为退出应用、热更新重装彻底不用 guard 了,或要重新安装新实例前必须先卸载旧的
clearRules()只清空规则,不动运行时状态临时关闭所有规则匹配只想让后续请求不再匹配规则,但在途请求的状态保留
javascript
// 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

详见 守护卸载与生命周期

基于 MIT 许可发布