在 Next.js 的 App Router 架构中,NextRequest 是处理请求的核心对象。它扩展了标准的 Web Request API,并提供了针对 Next.js 场景优化的便捷方法,尤其适用于 Middleware 和 Route Handlers。
1. 什么是 NextRequest?
NextRequest 是对原生 Request 对象的增强封装,主要提供以下能力:
- 便捷操作 Cookies
- 访问和解析 URL 路径、查询参数、basePath 等
- 与 Next.js App Router 深度集成
⚠️ 注意:
NextRequest仅在 Middleware 和 Route Handlers (如app/api/route.ts)中可用。
2. 基本使用场景
2.1 在 Middleware 中使用
ts
// middleware.ts
import { NextRequest, NextResponse } from 'next/server';
export function middleware(request: NextRequest) {
// 获取 URL 路径
console.log('Path:', request.nextUrl.pathname);
// 获取查询参数
const name = request.nextUrl.searchParams.get('name');
console.log('Query name:', name);
// 设置 Cookie
request.cookies.set('visited', 'true');
// 读取 Cookie
const theme = request.cookies.get('theme')?.value || 'light';
console.log('User theme:', theme);
return NextResponse.next();
}
2.2 在 Route Handler 中使用
ts
// app/api/user/route.ts
import { NextRequest, NextResponse } from 'next/server';
export async function GET(request: NextRequest) {
// 获取查询参数
const id = request.nextUrl.searchParams.get('id');
// 读取所有 cookies
const allCookies = request.cookies.getAll();
console.log('All cookies:', allCookies);
if (!id) {
return NextResponse.json({ error: 'Missing id' }, { status: 400 });
}
return NextResponse.json({ userId: id, cookies: allCookies });
}
3. 操作 Cookies
NextRequest.cookies 提供了完整的 Cookie 读写 API:
3.1 设置 Cookie
ts
request.cookies.set('show-banner', 'false');
// 结果:Set-Cookie: show-banner=false; Path=/
默认 Path 为当前请求路径。可通过选项自定义:
ts
request.cookies.set('token', 'abc123', {
path: '/',
maxAge: 60 * 60 * 24, // 1 天
httpOnly: true,
});
3.2 读取 Cookie
ts
const banner = request.cookies.get('show-banner');
console.log(banner?.value); // 'false' 或 undefined
3.3 批量读取或删除
ts
// 获取所有名为 'experiment' 的 Cookie(支持多值)
const experiments = request.cookies.getAll('experiments');
// 获取所有 Cookie
const all = request.cookies.getAll();
// 删除 Cookie
const deleted = request.cookies.delete('temp-token'); // 返回 boolean
// 清空所有 Set-Cookie 头
request.cookies.clear();
3.4 检查是否存在
ts
if (request.cookies.has('auth-token')) {
// 用户已登录
}
4. 解析 URL 信息
request.nextUrl 是对原生 URL 的扩展,提供更友好的访问方式:
ts
// 请求 URL: https://example.com/docs?version=15
console.log(request.nextUrl.pathname); // "/docs"
console.log(request.nextUrl.searchParams.get('version')); // "15"
console.log(request.nextUrl.basePath); // ""(若配置了 basePath 则返回)
console.log(request.nextUrl.toString()); // 完整 URL 字符串
💡
nextUrl是 只读副本 ,修改它不会影响原始请求。如需重写 URL,请使用NextResponse.rewrite()或redirect()。
5. 实战示例:权限中间件
以下是一个基于 Cookie 的简单权限控制中间件:
ts
// middleware.ts
import { NextRequest, NextResponse } from 'next/server';
export function middleware(request: NextRequest) {
const token = request.cookies.get('auth-token')?.value;
// 未登录且访问受保护路径
if (!token && request.nextUrl.pathname.startsWith('/dashboard')) {
const url = new URL('/login', request.url);
url.searchParams.set('redirect', request.nextUrl.pathname);
return NextResponse.redirect(url);
}
// 已登录用户访问登录页,跳转首页
if (token && request.nextUrl.pathname === '/login') {
return NextResponse.redirect(new URL('/dashboard', request.url));
}
return NextResponse.next();
}
export const config = {
matcher: ['/dashboard/:path*', '/login'],
};
6. 注意事项
NextRequest不能用于 Client Components,仅限服务端(Middleware / Route Handlers)。request.nextUrl.buildId在 App Router 中始终为undefined。- 国际化(i18n)相关属性(如
locale)在 App Router 中不可用,需通过其他方式处理。 - 自 Next.js v15.0.0 起,
request.ip和request.geo已被移除,请使用平台特定方案(如 Vercel 的x-vercel-ip头)。
总结
NextRequest 是 Next.js App Router 中处理 HTTP 请求的强大工具,尤其在需要操作 Cookie、解析 URL 或实现中间件逻辑时非常实用。通过其增强的 API,开发者可以更简洁、安全地编写服务端逻辑。
合理使用 NextRequest,能显著提升应用的灵活性与可维护性。