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

NextJS 13 App Router中如何在page.jsx返回404页面及状态码?

解决Next.js页面显示404但返回200状态码的问题

你这段代码的核心问题有两个:一是没等resData.json()异步操作完成,导致postData是个Promise对象,if(postData)永远为真,notFound()根本没机会执行;二是你的API路由在slug无效时返回的是200状态码,而非404,这也会导致状态码不符合预期。按下面的步骤调整就能解决:

1. 修正Page组件的逻辑

补全异步处理流程,同时增加响应状态码检查:

import { notFound } from 'next/navigation'

const PostViewPage = async ({ params }) => {
  const { slug } = params;
  const resData = await fetch(`/api/post/${slug}`);

  // 先检查API返回状态码,若为404直接触发404页面
  if (!resData.ok) {
    if (resData.status === 404) {
      notFound();
    }
    // 其他错误可按需自定义处理
    throw new Error('获取文章失败');
  }

  // 必须加await,否则拿到的是Promise而非真实数据
  const postData = await resData.json();

  // 额外检查数据是否为空,防止API返回200但无数据的情况
  if (!postData) {
    notFound();
  }

  // 此处编写你的业务逻辑与JSX代码
  return (<>JSX代码</>)
}

export default PostViewPage;

2. 让API路由返回正确的404状态码

无论你使用App Router还是Pages Router,都需要在slug无效时主动返回404状态码,而非200加空内容:

App Router 版本(app/api/post/[slug]/route.ts)

import { NextResponse } from 'next/server';

export async function GET(request: Request, { params }: { params: { slug: string } }) {
  const { slug } = params;
  // 替换为你从数据库/数据源获取文章的实际逻辑
  const post = await getPostBySlug(slug);

  if (!post) {
    // 重点:返回404状态码
    return NextResponse.json({ message: '文章不存在' }, { status: 404 });
  }

  return NextResponse.json(post);
}

Pages Router 版本(pages/api/post/[slug].ts)

import type { NextApiRequest, NextApiResponse } from 'next';

export default async function handler(req: NextApiRequest, res: NextApiResponse) {
  const { slug } = req.query;
  const post = await getPostBySlug(slug as string);

  if (!post) {
    return res.status(404).json({ message: '文章不存在' });
  }

  res.status(200).json(post);
}

调整完成后,无论是浏览器访问无效slug,还是用Postman请求,都会返回404状态码,同时浏览器会显示Next.js的404页面。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 22:52:15