Next.js 13 App Router如何仅捕获页面请求而非内部请求?
在Next.js 13 App Router中实现带排除规则的Catch-All路由
要解决根目录catch-all路由捕获内部请求的问题,同时保留App Router特性,最佳方案是结合Middleware过滤请求,让_next/、api/等路径走Next.js默认处理,其余路由由catch-all页面接管。
步骤1:创建Middleware过滤排除路径
在项目根目录新建middleware.js(或middleware.ts),通过它拦截请求并放行需要排除的路径:
import { NextResponse } from 'next/server'; export function middleware(request) { const { pathname } = request.nextUrl; // 定义需要跳过catch-all的路径前缀 const excludedPrefixes = ['/api/', '/_next/', '/favicon.ico', '/robots.txt']; // 判断当前请求是否属于排除项 const shouldBypass = excludedPrefixes.some(prefix => pathname.startsWith(prefix)); if (shouldBypass) { // 让Next.js默认处理这些请求 return NextResponse.next(); } // 非排除请求继续流向catch-all路由 return NextResponse.next(); } // 指定Middleware匹配所有请求路径 export const config = { matcher: '/:path*', };
步骤2:配置根目录Catch-All路由
在app/[...urlParts]/page.js中编写页面逻辑,处理解析URL、查询数据库、生成页面的核心需求:
import { cache } from 'react'; // 用React cache缓存数据库查询,复用App Router的缓存机制 const getPageData = cache(async (urlSegments) => { // 替换为你的数据库查询逻辑,比如按路径分段查询内容 const response = await fetch(`your-database-api/path/${urlSegments.join('/')}`, { next: { revalidate: 300 } // 可选:设置5分钟的重新验证时间 }); return response.json(); }); export default async function DynamicPage({ params }) { const { urlParts } = params; // 解析完整路径:比如urlParts为['blog', '2024', 'post']对应/blog/2024/post const fullPath = urlParts.join('/'); // 查询数据库数据 const pageContent = await getPageData(urlParts); // 生成页面内容,可结合App Router的组件、缓存特性 return ( <main> <h1>页面路径:/{fullPath}</h1> <div dangerouslySetInnerHTML={{ __html: pageContent.html }} /> </main> ); } // 可选:如果需要静态预生成部分路径,添加generateStaticParams // export async function generateStaticParams() { // // 返回需要预生成的路径分段数组 // return [ // { urlParts: ['about'] }, // { urlParts: ['blog', 'intro'] } // ]; // } // 全局缓存策略:设置页面重新验证时间(可选) export const revalidate = 60; // 每60秒重新验证一次页面数据
关键说明
- Middleware作用:确保
_next/(静态资源、内部脚本)、api/(接口请求)等路径不进入catch-all路由,完全由Next.js默认处理。 - Catch-All参数:
params.urlParts是路径分段的数组,可直接用来解析请求URL的结构。 - App Router特性复用:通过
cache函数、revalidate、generateStaticParams等实现页面缓存、增量静态再生等特性,无需切换回Pages Router。 - 无需额外URL前缀:根目录的
[...urlParts]路由直接处理所有非排除请求,URL中不会出现pages/这类冗余前缀。
内容的提问来源于stack exchange,提问作者Victor Gorban
相关产品推荐
相关产品推荐

