Next.js App Router替代getServerSideProps实现动态路由参数验证
在Next.js App Router中实现动态路由参数验证
在App Router中,你可以通过以下几种方式实现和Pages Router里getServerSideProps类似的动态路由参数验证逻辑:
1. 服务器组件内直接验证(最直接的替代方案)
App Router的页面组件默认是服务器组件,支持异步逻辑,你可以直接在组件内部完成参数验证,无效时触发404页面。
示例代码(app/[id]/page.tsx):
import { notFound } from 'next/navigation'; export default async function Page({ params }: { params: { id: string } }) { // 验证id是否为有效数字 const id = parseInt(params.id, 10); if (isNaN(id)) { // 触发全局404页面(app/not-found.tsx) notFound(); } // 后续业务逻辑:比如调用API验证id是否存在、获取数据 // const item = await fetch(`/api/items/${id}`).then(res => res.json()); // if (!item) notFound(); return ( <div> <h1>详情页:ID {id}</h1> {/* 渲染页面内容 */} </div> ); }
说明:调用notFound()后,Next.js会自动渲染你在app/not-found.tsx中定义的404页面,效果和Pages Router中返回{ notFound: true }完全一致。
2. 使用Middleware做全局路由拦截
如果多个动态路由需要统一的参数校验规则,或者想在请求到达页面组件前就拦截无效请求,可以使用Middleware。
示例代码(middleware.ts):
import { NextResponse } from 'next/server'; import type { NextRequest } from 'next/server'; export function middleware(request: NextRequest) { // 提取动态路由中的id参数(假设路由为/app/[id]/page.tsx) const pathSegments = request.nextUrl.pathname.split('/'); const id = pathSegments[pathSegments.length - 1]; if (id) { const parsedId = parseInt(id, 10); if (isNaN(parsedId)) { // 重定向到全局404页面 return NextResponse.redirect(new URL('/not-found', request.url)); // 也可以直接返回404响应 // return new NextResponse('无效的ID参数', { status: 404 }); } } } // 指定Middleware生效的路由匹配规则 export const config = { matcher: '/:id*', // 匹配所有以动态id结尾的路由,可根据实际路由调整 };
说明:Middleware在请求处理的最前期运行,适合做全局的参数校验、权限拦截等逻辑,避免重复代码。
3. 静态生成场景:用generateStaticParams预验证
如果你的页面是静态生成的,可以通过generateStaticParams提前生成所有有效的路由参数,无效参数的访问会直接返回404。
示例代码(app/[id]/page.tsx):
// 预生成所有有效的id参数 export async function generateStaticParams() { // 从API或数据库获取所有有效ID const validItems = await fetch('/api/items').then(res => res.json()); return validItems.map(item => ({ id: item.id.toString() })); } export default function Page({ params }: { params: { id: string } }) { const id = parseInt(params.id, 10); // 由于generateStaticParams只生成有效ID,此处可省略额外验证(动态新增内容除外) return <div>静态详情页:ID {id}</div>; }
说明:这种方式适合内容相对固定的静态站点,提前构建所有有效路由,无效路由会被Next.js自动拦截返回404。
内容的提问来源于stack exchange,提问作者Jeppe Christensen
相关产品推荐
相关产品推荐

