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

Next.js调用notFound()返回404页面但响应码为200问题排查

解决方案:让Next.js App Router同时返回404页面和404状态码

问题根源

你的代码中使用Promise.all并行发起验证请求与其他数据请求,当验证请求失败后调用notFound()时,其他请求可能已开始处理,导致Next.js无法正确设置404响应状态码。此外,若页面被静态缓存,也会出现状态码不匹配的情况。

修复步骤

1. 优先单独执行验证请求

不要并行发起验证和其他请求,先完成验证逻辑,确认通过后再获取其他数据。这样能确保验证失败时立即终止页面渲染,让Next.js正确设置404状态码。

修改后的代码:

// page.tsx
import { CategoryPage } from './CategoryPage';
import CategoryHead from './CategoryHead';
import { notFound } from 'next/navigation';

export default async function ExamCategoryPage({ params }: { params: { category: string } }) {
  const { category } = params;
  
  // 先执行验证请求,失败直接返回404
  const validationRes = await fetch(
    `${process.env.NEXT_PUBLIC_BASE_URL}/api/categories/validate-path/${category}`,
    { next: { revalidate: 900 } }
  );

  if (!validationRes.ok) {
    notFound();
  }

  // 验证通过后,再获取其他数据
  const [categoryRes, examRes] = await Promise.all([
    fetch(`${process.env.NEXT_PUBLIC_BASE_URL}/api/categories/slug/${category}`, {
      next: { revalidate: 1200 }
    }),
    fetch(`${process.env.NEXT_PUBLIC_BASE_URL}/api/exam/exam/${category}`)
  ]);

  const [categoryData, examData] = await Promise.all([
    categoryRes.json(),
    examRes.json()
  ]);

  if (!categoryData.success) {
    notFound();
  }

  return (
    <div>
      <CategoryHead 
        category={categoryData.data}
        subcategories={categoryData.data.children || []}
      />
      <CategoryPage examData={examData.success ? examData.data : null} />
    </div>
  );
}

2. 确保验证API返回正确的4xx状态码

确认/api/categories/validate-path/${category}接口在路径无效时,返回404或其他4xx系列状态码,而非200加错误信息。validationRes.ok仅识别200-299的状态码为成功,若接口返回200但success: false,则不会触发notFound()。

3. 禁用静态缓存(可选)

如果页面被静态生成,可能导致状态码被缓存为200。可在页面级别强制服务器端渲染:

export const dynamic = 'force-dynamic';

或在fetch中添加cache: 'no-store'(适用于动态内容场景)。

验证效果

修改后访问无效的category路径时:

  • 页面会显示Next.js默认404页面
  • 网络面板中页面请求的响应码应为404

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 21:42:42