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

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后没有抛出错误,函数可能继续执行,干扰跳转逻辑;同时未区分服务器端和客户端环境的操作,导致部分代码执行异常。

解决方案

  1. 区分客户端/服务器端环境执行操作
    在处理客户端专属逻辑(路由跳转、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');
    }
    
  2. 修正错误处理流程
    在catch块中处理完401逻辑后,必须抛出错误,确保函数不会继续执行后续代码,同时让调用方可以捕获错误做进一步处理。

  3. 适配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('/');
    
  4. 服务器端场景的重定向处理
    如果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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 17:09:32