Next.js中如何为可选捕获所有段路由设置严格规则?
Next.js 严格路由规则的实现方案
根据你的需求,不能用可选捕获所有路由([[...section]]),因为会放行非法路径,下面分两种路由体系给出具体实现方式:
App Router(Next.js 13+)
步骤1:按允许的路由创建文件结构
直接通过文件系统路由精确匹配合法路径,结构如下:
app/ └── path/ └── to/ ├── sectionA/ │ └── page.tsx ├── sectionB/ │ └── page.tsx └── sectionC/ ├── page.tsx ├── subA/ │ └── page.tsx └── subB/ ├── page.tsx └── [dynamic]/ └── page.tsx
这样path/to/sectionB/whatever这类非法路径会自动触发Next.js的404,因为没有对应的路由文件。
步骤2:校验动态路由参数
对于subB下的动态路径(dynamic1/dynamic2/dynamic3/dynamicX),需要在[dynamic]/page.tsx里校验参数合法性:
// app/path/to/sectionC/subB/[dynamic]/page.tsx import { notFound } from 'next/navigation'; export default function DynamicPage({ params }: { params: { dynamic: string } }) { const allowedDynamics = ['dynamic1', 'dynamic2', 'dynamic3', 'dynamicX']; if (!allowedDynamics.includes(params.dynamic)) { notFound(); // 触发404跳转 } return <div>Content for {params.dynamic}</div>; }
Pages Router(Next.js 12及更早)
步骤1:创建对应路由文件
同样通过文件系统路由定义合法路径:
pages/ └── path/ └── to/ ├── sectionA.tsx ├── sectionB.tsx └── sectionC/ ├── index.tsx ├── subA.tsx ├── subB.tsx └── subB/ └── [dynamic].tsx
非法路径如path/to/sectionB/whatever会自动返回404。
步骤2:校验动态参数
在[dynamic].tsx中通过getServerSideProps校验:
// pages/path/to/sectionC/subB/[dynamic].tsx import { GetServerSideProps } from 'next'; export default function DynamicPage({ dynamic }: { dynamic: string }) { return <div>Content for {dynamic}</div>; } export const getServerSideProps: GetServerSideProps = async ({ params }) => { const allowedDynamics = ['dynamic1', 'dynamic2', 'dynamic3', 'dynamicX']; const dynamicParam = params?.dynamic as string; if (!allowedDynamics.includes(dynamicParam)) { return { notFound: true, // 返回404 }; } return { props: { dynamic: dynamicParam }, }; };
如果是静态生成场景,改用getStaticPaths预定义所有合法动态路径,配合getStaticProps:
export async function getStaticPaths() { return { paths: [ { params: { dynamic: 'dynamic1' } }, { params: { dynamic: 'dynamic2' } }, { params: { dynamic: 'dynamic3' } }, { params: { dynamic: 'dynamicX' } }, ], fallback: false, // 未预定义的路径直接返回404 }; }
备选方案:全局Middleware拦截
如果路由规则频繁变动,或需要统一管理所有合法路由,可使用Middleware:
// middleware.ts import { NextResponse } from 'next/server'; import type { NextRequest } from 'next/server'; const allowedRoutes = new Set([ '/path/to/sectionA', '/path/to/sectionB', '/path/to/sectionC', '/path/to/sectionC/subA', '/path/to/sectionC/subB', '/path/to/sectionC/subB/dynamic1', '/path/to/sectionC/subB/dynamic2', '/path/to/sectionC/subB/dynamic3', '/path/to/sectionC/subB/dynamicX', ]); export function middleware(request: NextRequest) { const path = request.nextUrl.pathname; if (!allowedRoutes.has(path)) { return new NextResponse(null, { status: 404 }); } return NextResponse.next(); } export const config = { matcher: '/path/to/:path*', // 只拦截该前缀下的请求 };
这种方式适合集中管理路由规则,但需要维护完整的路由列表,新增路由时要同步更新。
内容的提问来源于stack exchange,提问作者axel
相关产品推荐
相关产品推荐

