Axios 安装模式
适用场景:项目使用 Axios,可一键接入(推荐)。
基本接入
import axios from 'axios';
import {
setupRequestGuard, // setup 安装方法
ConsoleRequestGuardLogger // 内置的日志类(也可继承 RequestGuardLogger 实现)
} from '@hydd/request-guard';
// setupRequestGuard(axios, options) → 返回 RequestGuardController
const requestManager = setupRequestGuard(axios, {
// 消息提示出口
notify: (payload) => Toast.show(payload.message),
// 日志观测
logger: new ConsoleRequestGuardLogger({ devOnly: true }),
// 全局规则
rules: [{ method: 'post', duplicate: true }]
});requestManager 是 RequestGuardController,可以调用:
configure(options)— 更新全局配置setRules(rules)— 覆盖全局规则addRule(rule)— 追加一条规则clearRules()— 清空所有规则clearState()— 清空所有能力状态getStateSnapshot()— 获取当前状态快照createLoadingKey()— 创建可复用的 loadingKeyisLoading(key)— 查询某个 key 是否仍在执行中subscribeLoading()— 订阅某个 key 的 loading 布尔变化uninstall()— 卸载守护,恢复 axios 原始行为circuitBreaker— 熔断器手动控制 API
完整方法说明见 RequestGuardController。
版本适配与覆盖面
覆盖面与 axios 版本和调用形式有关。本节帮你确认:你的版本和用法下,哪些请求受守护。
基本接入姿势
方式一:传入 axios,统一治理
import axios from 'axios';
import { setupRequestGuard } from '@hydd/request-guard';
// 在 axios.create 之前进行注册
setupRequestGuard(axios);
const service = axios.create({ baseURL: '/api' });接入后 create() 的实例都受守护。适合在应用入口统一接管。
方式二:传入单个实例,只守护该实例
const service = axios.create({ baseURL: '/api' });
setupRequestGuard(service);同副本内其他实例不受影响。适合只治理某个已知客户端。
版本表现
常用版本(0.x / 1.0 – 1.1 / ≥ 1.5.0):按上面姿势走即可。
- ⚠️
≥ 1.5.0下,若用service(config)这种可调用直调形态,需补一个source:
setupRequestGuard(service, {
axios: { source: axios } // 让 service(config) 也受守护
});特殊版本(1.2.0 – 1.4.x):只有传入对象的命名方法(axios.post / service.post)会正常守护,其他调用形式(可调用直调 service(config)、之后 create() 的派生实例)会默默失效。
解决方案是开启 forceGuard:
setupRequestGuard(service, {
axios: { source: axios, forceGuard: true }
});forceGuard 的代价
开启后守护会扩大到该 axios 副本内所有实例(含第三方 SDK 使用同一副本时的请求),会牺牲实例隔离。
多份 axios 模块
如果项目里存在多份 axios 模块(monorepo 依赖重复 / 第三方 SDK 内置 axios),需要每份各自接入——守护装在 A 副本上,B 副本的请求不受守护,也没有运行期信号。
兼容性经 29 个 axios 版本验证:0.27.2 → 1.19.0。
覆盖面速查表
| 接入方式 | 0.x / 1.0 – 1.1 | 1.2.0 – 1.4.x | ≥ 1.5.0 |
|---|---|---|---|
| 传 axios(统一治理) | ✅ 全部调用形式 | ⚠️ 仅命名方法(axios.post 等) | ✅ 全部调用形式 |
| 传单个实例 | ✅ 该实例全部调用形式 | ⚠️ 仅命名方法(service.post 等) | ⚠️ 命名方法受守护;service(config) 直调需补 axios.source |
表中“全部调用形式”指命名方法(
get/post/ …)与可调用直调(axios(config)/service(config))。接入前已创建的实例不受守护(见下方注意事项 ①)。
接入注意事项
- 接入顺序:传 axios 默认导出时,接入必须先于
axios.create()——接入前已创建的实例不受守护,且没有运行期信号提示。 - 多份 axios 模块:守护装在 A 副本,B 副本(monorepo 依赖重复 / 第三方 SDK 内置)不受守护,无信号。每份各自接入。
- 版本缺口:见上文“版本表现”。
axios 选项配置参考
| 字段 | 类型 | 默认 | 说明 |
|---|---|---|---|
axios.source | axios 模块对象 | — | 让“传实例 + 可调用直调”受守护;必须是创建该实例的同一份 axios 模块 |
axios.forceGuard | boolean | false | 覆盖 1.2.0 – 1.4.x 特殊版本下失效的调用形式;开启后作用于整个 axios 副本,会牺牲实例隔离 |
axios: { source, forceGuard }仅在 Axios 安装模式可用。
与外部按钮 loading 协作
如果你希望按钮、局部骨架屏、弹窗提交态等 UI 直接复用 guard 的执行态,可以使用 loadingKey(完整语义、并发计数与框架示例见 Loading 协作 API):
import axios from 'axios';
import {
createLoadingKey,
isLoading,
setupRequestGuard,
subscribeLoading
} from '@hydd/request-guard';
setupRequestGuard(axios, {
rules: [{ method: 'post', duplicate: true }]
});
const submitLoadingKey = createLoadingKey('submit-order');
const unsubscribe = subscribeLoading(submitLoadingKey, (loading) => {
console.log('submit button loading:', loading);
});
await axios.post('/api/order/submit', { orderId: '12345' }, {
requestGuard: {
duplicate: true,
loadingKey: submitLoadingKey
}
});
console.log(isLoading(submitLoadingKey)); // false
unsubscribe();如果项目依赖精准区分实例、希望跨版本行为完全一致,或命中上述注意事项且无法调整,可以考虑 Wrapper 模式——它不依赖 axios 版本相关的行为。

