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

React+Redux项目中Axios调用API无响应,第二个请求报401错误如何解决

问题根因

1. 请求执行顺序错误

你预期两个接口按顺序调用,但实际使用Promise.all让两个请求并行发送,获取packs的请求发出时,登录请求还未完成JWT的获取和本地存储写入,请求无有效鉴权信息,直接触发401。

2. packs请求未携带鉴权头

现有axios.get调用未在请求头中携带Authorization字段,后端无法识别用户身份,即使本地存了token也会触发鉴权失败。

3. packs reducer数据结构不统一

packs reducer初始值为数组,触发FETCH_PACK时返回的是包含packs属性的对象,导致state.packs数据结构前后不一致,出现空数组的异常表现。

4. 登录态判断导致提前跳转

当你从localStorage读取token设置initialState.isLogged为true时,Login组件渲染时会直接触发<Redirect to="/",登录和数据获取逻辑还未执行就跳走,无法拿到正确返回结果。

修复方案

调整请求逻辑为串行执行,补充鉴权头

替换原有Promise.all部分的代码,先完成登录再请求packs,同时在请求中携带token:

const handleSubmit = async (e) => {
  e.preventDefault();
  const data = {
    email: email,
    password: password,
  };
  try {
    // 先执行登录请求
    const loginRes = await axios.post(process.env.REACT_APP_LOGIN_URL_API, data);
    const token = loginRes.data.token;
    localStorage.setItem("token", token);
    dispatch(setLogin());
    // 登录成功后再请求packs,携带鉴权头
    const packRes = await axios.get(process.env.REACT_APP_PACK_URL, {
      headers: {
        Authorization: `Bearer ${token}`
      }
    });
    dispatch(getPacks(packRes.data.packs));
  } catch (err) {
    console.log("请求失败:", err);
  }
};

如果所有请求都需要携带token,建议配置axios全局拦截器,自动从localStorage读取token添加到请求头,避免重复编写header逻辑。

统一packs reducer数据结构

如果保持packs state为数组格式,修改reducer如下:

const packs = (state = [], action) => {
  switch (action.type) {
    case "FETCH_PACK":
      return action.payload.packs;
    default:
      return state;
  }
};

如果需要存储为对象格式,将初始值改为{packs: []},后续取值时使用state.packs.packs即可。

优化登录跳转逻辑

新增加载状态判断,避免页面刚渲染、还未验证token有效性就直接跳转,也可以将鉴权逻辑抽离到路由层,限制Login页面仅对未登录用户开放。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 19:45:04