NextJS not-found.tsx返回HTTP 200状态码问题排查与解决
NextJS not-found.tsx 返回200而非404的原因与修复方法
可能的原因及修复方案
1. App Router 未主动调用 notFound() 函数
在App Router中,not-found.tsx只是负责展示404页面的UI组件,不会自动触发404状态码。必须在匹配当前路径的页面组件(比如动态路由的page.tsx)中,当检测到数据不存在或路径无效时,手动调用notFound()函数,才能让服务器返回正确的404状态码。
修复:
在对应页面组件中添加资源校验逻辑,触发404状态:
// app/posts/[id]/page.tsx import { notFound } from 'next/navigation'; import { getPostById } from '@/lib/posts'; export default async function PostPage({ params }: { params: { id: string } }) { const post = await getPostById(params.id); if (!post) { // 触发404状态码并渲染not-found.tsx notFound(); } return <div>{post.title}</div>; }
2. Pages Router 未在数据获取函数中设置 notFound: true
如果使用Pages Router(pages/目录结构),pages/404.js会在路由匹配失败时自动渲染,但对于动态路由(比如pages/posts/[id].js),必须在getStaticProps或getServerSideProps中返回{ notFound: true },才能让服务器返回404状态码。
修复:
在数据获取函数中添加无效资源判断:
// pages/posts/[id].js export async function getStaticProps({ params }) { const post = await getPostById(params.id); if (!post) { return { notFound: true, }; } return { props: { post }, }; }
3. 路由匹配优先级导致未触发404
如果项目中存在catch-all路由(比如App Router的app/[...slug]/page.tsx或Pages Router的pages/[...slug].js),这类路由会匹配所有未被其他路由覆盖的路径。如果没有在该路由组件中处理无效路径的情况,服务器会默认返回200状态码,不会触发404。
修复:
在catch-all路由组件中添加路径有效性校验,无效时触发404:
// app/[...slug]/page.tsx import { notFound } from 'next/navigation'; export default async function CatchAllPage({ params }: { params: { slug: string[] } }) { // 根据slug判断路径是否有效,比如检查对应资源是否存在 const isValidPath = await checkValidPath(params.slug); if (!isValidPath) { notFound(); } return <div>Valid Path Content</div>; }
4. 缓存机制导致状态码被保留
NextJS的静态生成(SSG)或增量静态再生(ISR)会缓存页面内容和状态码。如果之前该路径被缓存为200,即使后续资源删除或路径失效,缓存未更新的情况下仍会返回200。
修复:
- 对于ISR页面,设置合理的
revalidate时间,或手动调用next revalidateAPI触发页面更新; - 开发环境下重启NextJS服务清除本地缓存;
- 生产环境下重新部署,或确保动态路由的数据获取逻辑不会缓存无效结果。
内容的提问来源于stack exchange,提问作者attiliov
相关产品推荐
相关产品推荐

