Next.js中API返回401时Router.push无法跳转页面问题排查
Next.js中postAPI函数401状态码时Router.push不跳转的问题
我在Next.js应用中编写了一个名为postAPI的通用函数,用于向后端服务器发送各类请求,代码如下:
import Router from 'next/router'; export const postAPI = async ( endpoint, data = {}, headers = {}, method = 'POST', options = {} ) => { const axios = require('axios'); const { parseCookies } = require('nookies'); const cookies = parseCookies(); const token = cookies[process.env.SESSION_TOKEN_NAME] || false; const config = { url: endpoint, method, data: data, headers: { authorization: headers.authorization ? headers.authorization : `Bearer ${token}`, }, ...options, }; const res = await axios(config).catch((err) => { if (err.response.status === 401) { Data.logoutUser(); setCookie(null, process.env.SESSION_TOKEN_NAME, null, { maxAge: 1, path: '/', }); deleteAllCookies(); Router.push('/'); window.localStorage.clear(); } }); return res?.data || res?.err; };
该函数可在任意Next.js组件中按需调用。我希望在API返回401状态码时将用户重定向至登录页,但使用next/router的Router.push并未实现跳转——虽然cookie和本地存储已被清除,但页面并未跳转到首页。请问我哪里操作出错了?
问题原因及解决方案
问题原因
- 环境不匹配:如果
postAPI在服务器端(SSR/SSG场景)执行,Router.push和window对象都无法正常工作——服务器端没有浏览器环境,客户端路由工具无法触发页面跳转,且window.localStorage会直接抛出错误中断逻辑。 - 错误处理逻辑不完整:
catch块中处理完401后没有抛出错误,函数可能继续执行,干扰跳转逻辑;同时未区分服务器端和客户端环境的操作,导致部分代码执行异常。
解决方案
区分客户端/服务器端环境执行操作
在处理客户端专属逻辑(路由跳转、localStorage操作)前,先判断当前环境:// 在catch块中修改 if (err.response.status === 401) { // 处理登出逻辑,若Data.logoutUser依赖客户端环境需加判断 if (typeof window !== 'undefined') { Data.logoutUser(); window.localStorage.clear(); } // 清除cookie(nookies的setCookie支持服务器端) setCookie(null, process.env.SESSION_TOKEN_NAME, null, { maxAge: 1, path: '/', }); deleteAllCookies(); // 仅在客户端执行路由跳转 if (typeof window !== 'undefined') { Router.push('/'); } // 抛出错误终止函数,避免后续逻辑干扰 throw new Error('Unauthorized'); }修正错误处理流程
在catch块中处理完401逻辑后,必须抛出错误,确保函数不会继续执行后续代码,同时让调用方可以捕获错误做进一步处理。适配App Router(Next.js 13+)
如果你的项目使用Next.js 13+的App Router,next/router已被废弃,需要改用next/navigation的useRouter钩子,且组件必须标记为客户端组件:'use client'; import { useRouter } from 'next/navigation'; // 在组件内初始化router const router = useRouter(); // 跳转时使用 router.push('/');服务器端场景的重定向处理
如果postAPI在服务器端(如getServerSideProps)被调用,无法通过客户端路由跳转,需要直接返回重定向响应:export async function getServerSideProps(context) { try { await postAPI('/api/your-endpoint'); } catch (err) { if (err.message === 'Unauthorized') { return { redirect: { destination: '/', permanent: false, }, }; } } return { props: {} }; }
内容的提问来源于stack exchange,提问作者Drashti Kheni
相关产品推荐
相关产品推荐

