Next.js中在Redux中间件实现401错误跳转至登录页
在Next.js+RTK Query项目中为401错误添加重定向逻辑
我有一个使用RTK Query处理API请求的Next.js项目,已实现名为errorMiddleware的API错误处理中间件,现有部分代码如下:
import { Middleware } from "@reduxjs/toolkit"; import { setMessage } from "../slice/toast"; const errorMiddleware: Middleware = (store) => (next) => (action: any) => { if (action.error && action.payload) { const status = String(action.payload.status); if (status.startsWith("5")) { store.dispatch( setMessage({ toastMessage: { code: action.payload.status, message: action.payload.data.message, severity: "error", }, }) ); } }
我希望添加一个条件,当错误状态码为401时将用户重定向至"/login"页面。以下是Redux Store中添加中间件的代码:
middleware: (getDefaultMiddleware) => getDefaultMiddleware({ serializableCheck: false, }).concat([ authApi.middleware, orderApi.middleware, botApi.middleware, exchangeApi.middleware, publicApi.middleware, userApi.middleware, errorMiddleware, ]),
解决方案
1. 补全中间件核心逻辑
首先要确保中间件调用next(action),否则会阻断Redux action的传递,导致RTK Query的正常流程失效。然后根据你的Next.js路由类型(Pages Router/App Router)添加401重定向逻辑:
针对Pages Router的实现
import { Middleware } from "@reduxjs/toolkit"; import { setMessage } from "../slice/toast"; import Router from 'next/router'; const errorMiddleware: Middleware = (store) => (next) => (action: any) => { if (action.error && action.payload) { const status = String(action.payload.status); if (status.startsWith("5")) { store.dispatch( setMessage({ toastMessage: { code: action.payload.status, message: action.payload.data.message, severity: "error", }, }) ); } // 新增401错误处理:重定向到登录页 if (status === "401") { Router.push('/login'); // 可选:清除用户认证状态,比如清空token // store.dispatch(clearAuthState()); } } // 必须调用next(action),否则action无法继续传递 return next(action); }; export default errorMiddleware;
针对App Router的实现
App Router中无法在Redux中间件这类非React组件环境直接使用useRouter Hook,因此采用客户端原生跳转方式:
import { Middleware } from "@reduxjs/toolkit"; import { setMessage } from "../slice/toast"; const errorMiddleware: Middleware = (store) => (next) => (action: any) => { if (action.error && action.payload) { const status = String(action.payload.status); if (status.startsWith("5")) { store.dispatch( setMessage({ toastMessage: { code: action.payload.status, message: action.payload.data.message, severity: "error", }, }) ); } // 新增401错误处理:客户端重定向到登录页 if (status === "401") { // 判断window是否存在,避免服务端渲染报错 if (typeof window !== 'undefined') { window.location.replace('/login'); } // 可选:清除用户认证状态 // store.dispatch(clearAuthState()); } } // 必须调用next(action) return next(action); }; export default errorMiddleware;
2. 关键注意事项
- 务必保留
return next(action):这是Redux中间件的核心要求,缺少会导致所有action被拦截,RTK Query无法完成请求生命周期。 - 401场景建议清除认证信息:避免后续请求携带无效凭证,可通过dispatch对应action清空Redux中的token等数据。
- 服务端渲染兼容:App Router的实现中加入了
typeof window !== 'undefined'判断,防止在服务端渲染阶段执行客户端专属代码报错。
内容的提问来源于stack exchange,提问作者Vala Khosravi
相关产品推荐
相关产品推荐

