从0死磕全栈之Next.js 中的 NextRequest 使用指南

在 Next.js 的 App Router 架构中,NextRequest 是处理请求的核心对象。它扩展了标准的 Web Request API,并提供了针对 Next.js 场景优化的便捷方法,尤其适用于 MiddlewareRoute Handlers


1. 什么是 NextRequest

NextRequest 是对原生 Request 对象的增强封装,主要提供以下能力:

  • 便捷操作 Cookies
  • 访问和解析 URL 路径、查询参数、basePath 等
  • 与 Next.js App Router 深度集成

⚠️ 注意:NextRequest 仅在 MiddlewareRoute 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:

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,
});
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.iprequest.geo 已被移除,请使用平台特定方案(如 Vercel 的 x-vercel-ip 头)。

总结

NextRequest 是 Next.js App Router 中处理 HTTP 请求的强大工具,尤其在需要操作 Cookie、解析 URL 或实现中间件逻辑时非常实用。通过其增强的 API,开发者可以更简洁、安全地编写服务端逻辑。

合理使用 NextRequest,能显著提升应用的灵活性与可维护性。

相关推荐
神秘的猪头4 小时前
ES6 字符串模板与现代 JavaScript 编程教学
前端·javascript
kaikaile19955 小时前
如何使用React和Redux构建现代化Web应用程序
前端·react.js·前端框架
江城开朗的豌豆5 小时前
TS类型进阶:如何把对象“管”得服服帖帖
前端·javascript
Cache技术分享5 小时前
226. Java 集合 - Set接口 —— 拒绝重复元素的集合
前端·后端
前端小咸鱼一条5 小时前
13. React中为什么使用setState
前端·javascript·react.js
没有bug.的程序员5 小时前
Spring Boot Actuator 监控机制解析
java·前端·spring boot·spring·源码
OpenTiny社区5 小时前
如何使用 TinyEditor 快速部署一个协同编辑器
前端·开源·编辑器·opentiny
IT_陈寒5 小时前
震惊!我用JavaScript实现了Excel的这5个核心功能,同事直呼内行!
前端·人工智能·后端
前端伪大叔6 小时前
freqtrade智能挂单策略,让你的资金利用率提升 50%+
前端·javascript·后端