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

React项目中axios请求返回401状态码时如何实现页面重定向?

问题根因

你当前写法的核心问题是:<Redirect> 是 React 提供的声明式路由组件,仅能在 React 组件的渲染上下文(组件的render方法/函数组件返回值)中生效,你在异步请求的catch回调里返回这个组件,不会被React渲染引擎识别,自然无法触发跳转。

解决方案

推荐使用命令式history跳转的方式实现非组件上下文的路由跳转,适配你当前的异步请求+redux-thunk的架构,具体操作如下:

步骤1:抽离公共history对象

因为react-router的路由跳转能力本质是基于history库实现的,我们把history实例抽成公共模块,就可以在任意JS文件中调用跳转能力:

  1. 新建src/utils/history.js文件,写入以下代码:
import { createBrowserHistory } from 'history'
export default createBrowserHistory()
  1. 如果安装后出现版本不兼容问题,执行命令安装适配react-router v5的版本:
    npm i history@4.10.1

步骤2:修改路由配置

把原来的BrowserRouter替换为基础Router,传入你自定义的history实例:

import { Router, Switch, Route } from "react-router";
import history from './utils/history' // 导入自定义history

const Container = () => {
    return (
        <div className="container">
            <Router history={history}>
                <Switch>
                    <Route path="/login">
                        <Login />
                    </Route>
                    <Route path="/register">
                        <Login />
                    </Route>
                    <Route path="/all-users">
                        <Alltasks />
                    </Route>
                    <Route path="/all-articles">
                        <AllUsers />
                    </Route>
                </Switch>
            </Router>
            <ToastContainer />
        </div>
    );
}

步骤3:修改请求逻辑

直接调用history的push方法触发跳转,不需要返回Redirect组件:

import axiosConfig from "../../config/axios";
import actions from "./actions";
import history from '../../utils/history' // 导入公共history

const fetchUser = async () => {
    try {
        const response = await axiosConfig.get('api/get-user')
        return response.data
    } catch (error) {
        console.log(error.response.status) // 401
        console.log(error.response.data.error) // Please Authenticate
        if (error.response.status === 401) {
            // 执行跳转,同时记录跳转前的路径,方便登录后跳回原页面
            history.push({
                pathname: '/login',
                state: { from: window.location.pathname }
            })
            // 抛出错误中断后续逻辑,避免dispatch无效数据
            throw new Error('用户未授权')
        }
        throw error
    }
}

export const getUser = () =>
    async (dispatch) => {
        try {
            const user = await fetchUser()
            dispatch(actions.setUser(user));
        } catch (err) {
            // 可在此处添加全局错误提示逻辑
            console.error(err)
        }
    }

优化方案:全局统一处理401

你也可以直接在axios的响应拦截器里统一处理所有接口的401错误,不用每个请求单独写判断,修改你的../../config/axios配置文件即可:

import axios from 'axios'
import history from '../utils/history'

const axiosConfig = axios.create({
  baseURL: '你的接口基础前缀',
  timeout: 10000
})

// 全局响应拦截器
axiosConfig.interceptors.response.use(
  response => response,
  error => {
    // 所有接口返回401都自动跳转登录页,同时清空本地缓存的身份信息
    if (error.response?.status === 401) {
      localStorage.removeItem('token')
      localStorage.removeItem('userInfo')
      history.push('/login')
    }
    return Promise.reject(error)
  }
)

export default axiosConfig

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 00:48:04