好知道: 路由处理程序仅在
app
目录中可用。它们相当于pages
目录中的 API 路由,这意味着您不需要同时使用 API 路由和路由处理程序。
路由处理程序在app
目录中的 route.js|ts 文件 中定义:
export const dynamic = 'force-dynamic' // 默认为自动
export async function GET(request: Request) {}
路由处理程序可以嵌套在app
目录中,类似于page.js
和layout.js
。但是在与page.js
相同的路由段级别上不能有route.js
文件。
支持以下HTTP方法:GET
、POST
、PUT
、PATCH
、DELETE
、HEAD
和OPTIONS
。如果调用了不受支持的方法,Next.js将返回405 Method Not Allowed
响应。
除了支持原生Request和Response之外,Next.js还通过NextRequest和NextResponse对其进行扩展,以提供便捷的辅助功能,满足高级用例的需求。
使用Response
对象的GET
方法时,默认情况下会缓存路由处理程序。
导出异步函数 GET() {
const res = await fetch('https://data.mongodb-api.com/...', {
headers: {
'Content-Type': 'application/json',
'API-Key': process.env.DATA_API_KEY,
},
})
const data = await res.json()
返回 Response.json({ data }) }
TypeScript 警告:
Response.json()
仅适用于 TypeScript 5.2。如果您使用较低版本的 TypeScript,您可以使用 NextResponse.json() 来代替类型化响应。
您可以选择退出缓存方式:
- 使用
GET
方法与Request
对象。 - 使用其他任何 HTTP 方法。
- 使用动态函数如
cookies
和headers
。 - Segment 配置选项手动指定动态模式。
例如:
export async function GET(request: Request) {
const { searchParams } = new URL(request.url)
const id = searchParams.get('id')
const res = await fetch(`https://data.mongodb-api.com/product/${id}`, {
headers: {
'Content-Type': 'application/json',
'API-Key': process.env.DATA_API_KEY!,
},
})
const product = await res.json()
返回 Response.json({ product }) } ```
同样,POST
方法将导致路由处理程序动态评估。
导出异步函数 POST() {
const res = await fetch('https://data.mongodb-api.com/...', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'API-Key': process.env.DATA_API_KEY!,
},
body: JSON.stringify({ time: new Date().toISOString() }),
})
const data = await res.json()
返回 Response.json(data) }```
值得知道:与 API 路由一样,路由处理程序可用于处理表单提交等情况。正在开发一种与 React 深度集成的新抽象,用于处理表单和变更。
你可以将 route
视为最低级别的路由基元。
- 他们不参与布局或客户端导航,比如
page
。 - 在与
page.js
相同的路由上不能有route.js
文件。
| 页面 | 路由 | 结果 | | -------------------- | ---------------- | -------- | | app/page.js | app/route.js | 冲突 | | app/page.js | app/api/route.js | 有效 | | app/[user/\/page.js | app/api/route.js | 有效 |
每个 route.js
或 page.js
文件接管该路由的所有 HTTP 动词。
导出默认函数 Page() {
返回 <h1>你好,Next.js!</h1>
}'
// ❌ 冲突
// app/route.js
export async function POST(request) {}
以下示例展示了如何将路由处理程序与其他 Next.js API 和功能结合使用。
您可以使用next.revalidate选项重新验证缓存数据:
导出异步函数 GET() {
const res = await fetch('https://data.mongodb-api.com/...', {
next: { revalidate: 60 }, // 每60秒重新验证一次
})
const data = await res.json()
返回 Response.json(data) }```
或者,您可以使用重新验证段配置选项:
导出常量重新验证 = 60
您可以使用next/headers读取或设置cookies。这个服务器函数可以直接在路由处理程序中调用,也可以嵌套在另一个函数中。
或者,您可以使用 Set-Cookie 标头返回一个新的 Response
。
import { cookies } from 'next/headers'
导出异步函数 GET(request: Request) { const cookieStore = cookies() const token = cookieStore.get('token')
return new Response('你好,Next.js!', {
status: 200,
headers: { 'Set-Cookie': token=${token.value}
},
})
}
您还可以使用底层的 Web API 从请求中读取 cookie(NextRequest):
import { type NextRequest } from 'next/server'
export async function GET(request: NextRequest) { const token = request.cookies.get('token') }
您可以使用next/headers
中的headers读取标题。此服务器函数可以直接在路由处理程序中调用,或嵌套在另一个函数中。
这个 headers
实例是只读的。要设置头部,您需要返回一个带有新 headers
的新 Response
。
从 'next/headers' 导入 { headers }
export async function GET(request: Request) { const headersList = headers() const referer = headersList.get('referer')
return new Response('你好,Next.js!', { status: 200, headers: { referer: referer }, }) }
您还可以使用底层的 Web API 从请求中读取标头(NextRequest):
import { type NextRequest } from 'next/server'
export async function GET(request: NextRequest) { const requestHeaders = new Headers(request.headers) }
import { redirect } from 'next/navigation'
导出异步函数 GET(request: Request) { 重定向('https://nextjs.org/') }
在继续之前,我们建议阅读定义路由页面。
Route Handlers可以使用动态片段从动态数据创建请求处理程序。