请求拦截器相关面试题

1. 请求拦截器和响应拦截器分别有什么作用?

请求拦截器管请求发出去之前的事,响应拦截器管请求回来之后的事。

继续追问:请求拦截器一般做什么?

最常见的就是统一加 Token、公共请求头和请求配置。 例如:

javascript 复制代码
axios.interceptors.request.use(config => {
  const token = getToken();

  if (token) {
    config.headers.Authorization = `Bearer ${token}`;
  }

  return config;
});

继续追问:响应拦截器一般做什么?

主要是统一处理响应数据和错误。 比如:

javascript 复制代码
axios.interceptors.response.use(
  response => {
    return response.data;
  },
  error => {
    if (error.response?.status === 401) {
      // Token 失效
    }

    return Promise.reject(error);
  }
);

2. 为什么要封装一层请求,而不是每个地方直接用 Axios?

就是把重复的请求逻辑统一掉,让业务代码只管调接口。

比如业务代码只需要:

javascript 复制代码
const user = await getUser();

而不用每个地方都写:

text 复制代码
加 Token
设置 Header
处理 401
处理错误
设置超时

3. Token 过期了怎么办?

收到 401 后刷新 Token,刷新成功再把原请求重新发一次。

流程:

text 复制代码
请求
 ↓
401
 ↓
刷新 Token
 ↓
成功
 ↓
重新请求原接口

4. 如果同时有很多请求都返回 401 呢?

不能让每个请求都去刷新 Token,只能同时刷新一次,其他请求等它。

例如:

text 复制代码
请求 A ──→ 401 ──┐
请求 B ──→ 401 ──┤
请求 C ──→ 401 ──┤
                  ↓
              刷新 Token
                  ↓
                成功
             ↙    ↓    ↘
           A重试  B重试  C重试

常见做法是共享一个 Promise:

javascript 复制代码
let refreshPromise = null;

async function refreshTokenOnce() {
  if (!refreshPromise) {
    refreshPromise = refreshToken()
      .finally(() => {
        refreshPromise = null;
      });
  }

  return refreshPromise;
}

核心就是:

同一时间只能有一个刷新请求。


5. Token 刷新失败怎么办?

刷新失败就不能继续重试了,一般清掉登录状态,让用户重新登录。

否则就会出现:

text 复制代码
401
 ↓
刷新失败
 ↓
重新请求
 ↓
401
 ↓
继续刷新
 ↓
......

所以必须有明确的失败出口。


6. 所有请求失败都应该自动重试吗?

不应该,要看失败原因和请求本身能不能安全重试。

例如:

text 复制代码
GET 查询
→ 一般可以考虑重试

POST 创建订单
→ 不能随便重试

支付请求
→ 更不能简单自动重试

因为有些请求重复执行会产生实际业务影响。


7. 怎么做请求重试?

一般会限制重试次数,而且只对明确可以重试的错误重试。

例如:

javascript 复制代码
async function requestWithRetry(request, maxRetry = 3) {
  let count = 0;

  while (true) {
    try {
      return await request();
    } catch (error) {
      count++;

      if (count > maxRetry || !canRetry(error)) {
        throw error;
      }

      await sleep(1000 * count);
    }
  }
}

这里还可以继续追问:

为什么不能无限重试?

因为网络异常可能一直存在,无限重试会把问题放大。


8. 请求去重是怎么做的?

核心就是给请求生成一个唯一 Key,相同请求正在执行时就不要重复发。

例如:

text 复制代码
method + url + params + body
             ↓
         requestKey

第一次:

text 复制代码
GET /user → 发请求

第二次:

text 复制代码
GET /user → 发现相同请求正在执行
        → 复用 / 取消

具体选择哪种,要看业务需求。


9. 怎么取消请求?

现在一般直接用 AbortController。

javascript 复制代码
const controller = new AbortController();

fetch('/api/user', {
  signal: controller.signal
});

// 取消
controller.abort();

典型场景就是搜索:

text 复制代码
输入 A
 ↓
请求 A

输入 AB
 ↓
取消 A
 ↓
请求 AB

输入 ABC
 ↓
取消 AB
 ↓
请求 ABC

避免旧请求回来以后把新数据覆盖掉。


10. 所有错误都在响应拦截器里弹 Toast,可以吗?

不建议,请求层负责识别和处理错误,具体怎么提示最好由业务决定。

因为不同接口的错误处理可能不一样:

text 复制代码
有的 → Toast
有的 → 页面展示
有的 → 静默处理
有的 → 自己处理

如果请求层直接绑定 UI,就容易变成:

text 复制代码
请求层
  ↓
Axios
  ↓
Toast
  ↓
具体 UI 框架

耦合会比较重。


11. 请求拦截器是不是只能 Axios 有?

不是,拦截请求是一个设计思路,不是 Axios 独有的功能。

Axios 自己提供了拦截器;如果用 fetch,也可以自己封装:

javascript 复制代码
async function request(url, options) {
  const config = beforeRequest(url, options);

  const response = await fetch(
    config.url,
    config.options
  );

  return afterResponse(response);
}

一道题怎么连续追?

面试官:

请求拦截器和响应拦截器有什么作用?

你先答:请求拦截器管请求发出去之前的事,响应拦截器管请求回来之后的事。

面试官继续:

Token 怎么处理?

请求拦截器统一加 Token。

Token 过期呢?

收到 401 就刷新 Token,成功后重发原请求。

如果同时 10 个请求都 401 呢?

不能让 10 个请求一起刷新,只能刷新一次,其他请求等刷新结果。

刷新失败呢?

清掉登录状态,让用户重新登录,不能继续重试。

那请求重试呢?

只重试明确可以安全重试的请求,而且要限制次数。

你还会考虑什么?

请求取消、请求去重、错误统一处理,这些都可以根据业务需要加。

这就比单纯回答"请求拦截器加 Token,响应拦截器处理错误"明显高一个层次。

相关推荐
学到老活到老7 小时前
Spring 事务怎样生效?为什么加了 @Transactional 仍不回滚?
java·spring
学到老活到老7 小时前
Spring 怎样创建 Bean?@Autowired 在哪一步生效?
java·spring
用户112936112197 小时前
我扫了项目里 739 个 Controller,发现最危险的越权漏洞不是没认证
java
小羊没烦恼!7 小时前
分布式事务 | 使用DTM 的Saga 模式
java·linux·运维·数据库·wpf
没事写点啥7 小时前
WeKnora 回答溯源
前端·后端·ai编程
JPower_mr.g7 小时前
SmartCall v1.0.9 发布:智能体知识库上线,让 AI 客服先查资料再回答
java·ide·人工智能·macos·架构·开源·xcode
SL_staff7 小时前
破除执行黑箱:用目标地图、资源热力图与健康度看板构建可下钻的执行事实链
java·开源·全栈
骑着蜗牛撵大象3277 小时前
让 Codex 值夜班:把告警排查与巡检接成可回滚的自动化链路
android·java·运维·ai·自动化·codex·智能体
木头科技8 小时前
【AI 工程化第十八篇】Spring AI 语音 Agent 实战:实时转写、WebSocket、流式 TTS 与打断机制
java·人工智能·安全·spring·性能优化
LuHang8 小时前
Vue3 大屏项目 MQTT 实战:机场与无人机 OSD 实时数据总线
前端