路由处理

2026年9月6日

页面用 page.tsx,接口用 route.ts。两边都按目录映射 URL,前端页面和后端处理可以放在同一个仓库。


文件放哪

app/
└── api/
    ├── user/route.ts      → /api/user
    ├── login/route.ts     → /api/login
    └── user/[id]/route.ts → /api/user/:id
text

page.tsxroute.ts 不能同目录,框架无法同时当页面又当接口。前后端代码分开放更清楚。

导出的函数名必须是 HTTP 方法,且全大写:GETPOSTPUTPATCHDELETEHEADOPTIONS。没写 OPTIONS 时,框架会补一份。


GET 和查询串

import { NextRequest, NextResponse } from "next/server";

export async function GET(request: NextRequest) {
  const id = request.nextUrl.searchParams.get("id");
  return NextResponse.json({ id });
}
ts

本地可以用 VS Code / Cursor 的 REST Client 插件,写一个 test.http

GET http://localhost:3000/api/user?id=123 HTTP/1.1
http

POST 和 body

export async function POST(request: NextRequest) {
  const body = await request.json();
  return NextResponse.json({ ok: true, body }, { status: 201 });
}
ts

按 Content-Type 选读法:request.json()formData()text()arrayBuffer()blob()

POST http://localhost:3000/api/user HTTP/1.1
Content-Type: application/json

{
  "name": "槿",
  "age": 18
}
http

动态段

第二参数里的 params 现在是 Promise:

export async function GET(
  _request: NextRequest,
  { params }: { params: Promise<{ id: string }> }
) {
  const { id } = await params;
  return NextResponse.json({ hello: id });
}
ts

/api/user/886 会得到 id === "886"


next/headerscookies() 在 Route Handler 里也能用。登录成功写 token、再提供检查接口,是常见写法:

import { cookies } from "next/headers";
import { NextRequest, NextResponse } from "next/server";

export async function POST(request: NextRequest) {
  const { username, password } = await request.json();
  if (username !== "admin" || password !== "demo") {
    return NextResponse.json({ ok: false }, { status: 401 });
  }

  const jar = await cookies();
  jar.set("token", "demo-token", {
    httpOnly: true,
    sameSite: "lax",
    maxAge: 60 * 60 * 24 * 30,
  });
  return NextResponse.json({ ok: true });
}

export async function GET() {
  const jar = await cookies();
  const token = jar.get("token");
  if (token?.value === "demo-token") {
    return NextResponse.json({ ok: true });
  }
  return NextResponse.json({ ok: false }, { status: 401 });
}
ts

httpOnly 让脚本读不到 cookie,能少一类 XSS 偷 token。正式环境还要 secure、短过期、真正的会话存储,这里只演示 API 形状。

客户端登录页用 fetch('/api/login', { method: 'POST', ... }),成功后再 router.push('/home')。保护页面可以再打一次 GET,或把检查挪到下一篇的 Proxy。

下一篇用 Vercel AI SDK 把对话接口接到页面上。


参考文档