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

Next.js 13服务端组件错误处理:401状态下Cookie无法删除

解决Next.js 13 Server Component中API错误状态处理问题

问题根源分析

  1. 返回类型冲突:getItems声明返回IGetItemsResponse,但401时返回了NextResponse,类型不匹配导致逻辑异常;且Server Component中不能直接返回Response对象,这是核心问题。
  2. 代码执行顺序漏洞:401状态下res.ok为false,即便执行了删除Cookie的逻辑,后续!res.ok判断仍会触发,抛出错误跳转到error.tsx。
  3. 生产环境错误屏蔽:Next.js生产环境默认会隐藏具体错误细节,避免泄露敏感信息,因此和开发环境显示内容不同。

修正后的代码实现

1. 正确处理401状态(删除Cookie+终止逻辑)

在Server Component中,直接使用Next.js提供的cookies() API操作Cookie,配合redirect()终止后续代码执行,确保逻辑生效:

import { cookies, redirect, notFound } from 'next/headers';

const getItems = async (): Promise<IGetItemsResponse> => {
  const res = await fetch(`${process.env.API_URL}items`, {
    headers: {
      Authorization: `Bearer ${cookies().get('access_token')?.value}`,
    },
  });

  if (res.status === 404) {
    notFound(); // 触发not-found.tsx,终止后续执行
  }

  if (res.status === 401) {
    // 直接删除目标Cookie
    cookies().delete('access_token');
    cookies().delete('expiry_token');
    // 重定向到登录页,彻底终止当前逻辑
    redirect('/login');
  }

  if (!res.ok) {
    // 处理其他非200/401/404的异常状态
    throw new Error(`API请求失败:${res.statusText}`);
  }

  return res.json();
};

export default async function Page() {
  const items = await getItems();
  return <ItemList initialData={items} />;
}

2. 自定义生产环境错误展示

在error.tsx中,通过错误信息标识自定义展示内容,避免生产环境的模糊提示:

'use client'; // error.tsx必须是Client Component

interface ErrorProps {
  error: Error & { digest?: string };
  reset: () => void;
}

export default function Error({ error, reset }: ErrorProps) {
  // 根据错误信息判断是否为授权过期
  const isAuthExpired = error.message.includes('401') || error.message.includes('Unauthorized');
  
  return (
    <div className="error-wrap">
      <h2>操作失败</h2>
      <p>{isAuthExpired ? '登录状态已过期,请重新登录' : error.message || '未知错误'}</p>
      <button onClick={() => reset()}>重试</button>
    </div>
  );
}

关键注意事项

  • Server Component中操作Cookie必须使用next/headers导出的cookies() API,不能通过NextResponse修改后返回,组件函数需返回UI或数据而非响应对象。
  • redirect()和notFound()都是终止执行的函数,调用后后续代码不会运行,能避免触发!res.ok的错误抛出。
  • 生产环境若需展示特定错误,需在抛出错误时明确携带标识(如状态码关键词),再在error.tsx中判断展示。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 13:30:21