从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,能显著提升应用的灵活性与可维护性。

相关推荐
辞忧*16 小时前
基于element-Plus的el-tooltip封装公共虚拟引用组件
前端·vue.js
by__csdn16 小时前
Electron入门:跨平台桌面开发指南
前端·javascript·vue.js·typescript·electron·html
Nan_Shu_61419 小时前
学习:ES6(2)
前端·学习·es6
命运之光1 天前
【最新】ChromeDriver最新版本下载安装教程,ChromeDriver版本与Chrome不匹配问题
前端·chrome
星离~1 天前
Vue响应式原理详解:从零实现一个迷你Vue
前端·javascript·vue.js
梦6501 天前
React 简介
前端·react.js·前端框架
一只小阿乐1 天前
react 中的判断显示
前端·javascript·vue.js·react.js·react
光影少年1 天前
useMemo 和 React.memo区别
前端·react.js·前端框架
小沐°1 天前
React-页码组件
前端·javascript·react.js