You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React中能否为fetch请求响应配置过滤器统一处理指定端点逻辑?

React项目统一处理fetch响应Refresh-Token存储方案

完全可以通过封装全局fetch请求层加响应拦截的方式实现,不需要在每个接口单独编写存储逻辑,具体实现如下:

第一步:封装通用请求工具

新建通用请求工具文件,统一处理公共请求逻辑、响应拦截逻辑,内置端点匹配规则,只对配置的接口执行Refresh-Token提取存储操作。

// src/utils/request.js
const BASE_URL = process.env.REACT_APP_PROXY;

// 配置需要自动提取Refresh-Token的接口匹配规则,支持字符串前缀、正则两种匹配方式
const TOKEN_REFRESH_RULES = [
  /^\/users\//, // 示例:匹配所有/users/前缀的接口
  // 后续新增接口直接在这里追加规则即可
];

/**
 * 校验当前请求地址是否命中Token自动处理规则
 * @param {string} requestUrl 完整请求地址
 * @returns {boolean}
 */
const isNeedHandleToken = (requestUrl) => {
  const apiPath = requestUrl.replace(BASE_URL, '');
  return TOKEN_REFRESH_RULES.some(rule => {
    if (typeof rule === 'string') return apiPath.startsWith(rule);
    if (rule instanceof RegExp) return rule.test(apiPath);
    return false;
  });
};

/**
 * 封装后的通用请求方法,全局替换原生fetch使用
 * @param {string} url 接口路径/完整地址
 * @param {object} fetchOptions 原生fetch支持的所有配置项
 * @returns {Promise<Response>} 和原生fetch返回一致的Promise对象
 */
const request = (url, fetchOptions = {}) => {
  // 合并默认请求配置
  const mergedOptions = {
    method: 'GET',
    headers: {
      'Content-Type': 'application/json',
      ...(fetchOptions.headers || {})
    },
    ...fetchOptions
  };

  // 自动注入鉴权请求头
  const storedToken = sessionStorage.getItem('token');
  if (storedToken) {
    mergedOptions.headers.Authorization = `Token ${storedToken}`;
  }

  // 拼接完整请求地址
  const fullUrl = url.startsWith('http') ? url : `${BASE_URL}${url}`;

  return fetch(fullUrl, mergedOptions).then(response => {
    // 统一响应拦截:命中规则、响应正常、存在Refresh-Token头时自动存储
    if (response.ok && isNeedHandleToken(fullUrl)) {
      const refreshToken = response.headers.get('Refresh-Token');
      if (refreshToken) {
        sessionStorage.setItem('token', refreshToken);
      }
    }
    // 将原始响应返回给业务层,保持和原生fetch使用体验一致
    return response;
  });
};

export default request;

第二步:替换业务代码中的原生fetch

所有原有调用原生fetch的地方,直接替换为引入封装好的request方法即可,原有业务逻辑基本不需要改动,重复的公共逻辑全部被封装层收口。
改写后的表单提交示例:

import request from '@/utils/request';

const handleFormSubmit = (e) => {
  e.preventDefault()
  if (password != passConfirm) {
    setErrors({passConfirm: ["Must match password"]})
    return
  }
  request('/users/', {
    method: 'POST',
    body: JSON.stringify({first_name, last_name, username, password, email})
  }).then((response) => {
    if (response.ok) {
      // 无需再手动编写Refresh-Token存储逻辑
      setRedirect(true)
    } else {
      setErrors(response)
      console.log(response)
    }
  })
}

方案优势

  • 逻辑高度收口:Token存储、鉴权头注入、baseURL拼接等公共逻辑只需要维护一处,后续修改存储方式、鉴权规则不需要改动业务代码
  • 配置成本极低:新增需要自动处理Token的接口时,只需要在TOKEN_REFRESH_RULES数组中追加一条匹配规则即可,不需要侵入业务逻辑
  • 扩展性强:后续需要新增统一错误提示、请求loading、超时控制、响应格式转换等全局逻辑时,直接在request封装层添加即可

注意:跨域场景下需要后端在响应头中配置Access-Control-Expose-Headers: Refresh-Token,否则前端无法通过JS读取到自定义的Refresh-Token响应头。

内容的提问来源于stack exchange,提问作者Dave

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 10:09:20