当前位置: 首页 > article >正文

Nextjs15 - middleware的使用

nextjs 官方文档(current branch 对应如下文档)

  • Middleware
  • path-to-regexp

本专栏内容均可在Github:test_05/Middleware 找到

一、middleware 基本使用

中间件允许您在请求完成之前运行代码。然后,根据传入的请求,您可以通过重写、重定向、修改请求或响应标头或直接响应来修改响应。

使用项目根目录中的 middleware.ts 文件(或 .js )来定义中间件。例如,与 pagesapp 处于同一级别,或者在 src 内(如果适用)。

注意 :
虽然每个项目仅支持一个 middleware.ts 文件,但您仍然可以模块化地组织中间件逻辑。将中间件功能分解为单独的 .ts 或 .js 文件,然后将其导入主 middleware.ts 文件。这样可以更清晰地管理路由特定的中间件,这些中间件会汇总在 middleware.ts 中以便进行集中控制。通过强制使用单个中间件文件,可以简化配置、防止潜在冲突并通过避免多个中间件层来优化性能。
Example:

/about/** 所有路由访问重定向到 /home,见:middleware.ts

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

export const middleware = (request: NextRequest) => {
  // 请求路由为 /about/** 重定向到 /home
  return NextResponse.redirect(new URL("/home", request.url));
};

/** 配置匹配路径 */
export const config = {
  matcher: "/about/:path*",
};

matcher 的语法参考 path-to-regexp

我们也可以不使用 matcher,而是在 middleware 中使用条件语句进行判断,见:middleware.ts

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

export const middleware = (request: NextRequest) => {
  // 将 url 开头为 /about 的请求重定向到 /home
  if (request.nextUrl.pathname.startsWith("/about")) {
    return NextResponse.redirect(new URL("/home", request.url));
  }
};

二、在中间件中使用 Cookies

Cookies 是常规标头。在 Request 中,它们存储在 Cookie 标头中。在 Response 中,它们位于 Set-Cookie 标头中。Next.js 通过 NextRequestNextResponse 上的 cookies 扩展提供了一种访问和操作这些 cookie 的便捷方法。

对于传入请求, cookies 具有以下方法:

  • get
  • getAll
  • set
  • delete cookies

您可以使用 has 检查 cookie 是否存在,或使用 clear 删除所有 cookie。

对于传出的响应, cookies 具有以下方法

  • get
  • getAll
  • set
  • delete

在这里插入图片描述

见:middleware.ts

/** 二、中间件中使用 cookies */
export const middleware = (request: NextRequest) => {
  // cookie { name: 'vercel', value: '31321' }
  console.log(request.cookies.get("vercel"));

  /**
   * cookies [
   * { name: 'vercel', value: '31321' },
   * { name: 'nextjs', value: '333' }
   * ]
   */
  console.log(request.cookies.getAll());

  // true
  console.log("1、is has vercel :", request.cookies.has("vercel"));

  request.cookies.delete("vercel");

  // false
  console.log("2、is has vercel :", request.cookies.has("vercel"));

  /** 设置 cookie */
  const response = NextResponse.next();
  response.cookies.set("vercel", "333");
  response.cookies.set({
    name: "vercel",
    value: "333",
    path: "/",
  });
  console.log("3、vercel:", response.cookies.get("vercel"));

  return response;
};

在这里插入图片描述

三、在中间件中使用 Headaers

我们可以使用 NextResponse API 设置请求和响应标头(自 Next.js v13.0.0 起可以设置请求标头)。
见:middleware.ts

/** 三、在中间件中使用 Headers */
export const middleware = (request: NextRequest) => {
  const headers = new Headers(request.headers);

  headers.set("token", "this is my token");

  // 通过 NextResponse.next() 的配置对象来修改请求
  const response = NextResponse.next({
    request: {
      headers: headers, // 修改请求头
    },
  });

  // 通过 response 的 headers 来修改响应头
  response.headers.set("token", "this is my token");
  return response;
};

四、在中间件中使用 CORS

我们可以在中间件中设置 CORS 标头以允许跨源请求,包括简单的并已预检要求。
见:middleware.ts

/** 四、在中间件中使用 CORS */
// 定义允许跨域访问的源站列表
const allowedOrigins = ["https://example.com", "https://sub.example.com"];

// 定义 CORS 相关的配置选项
const corsOptions = {
  // 允许的 HTTP 请求方法
  "Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, OPTIONS",
  // 允许的请求头
  "Access-Control-Allow-Headers": "Content-Type, Authorization",
};

export const middleware = (request: NextRequest) => {
  // 获取请求的源站地址,如果没有则设为空字符串
  const origin = request.headers.get("origin") ?? "";
  // 检查请求的源站是否在允许列表中
  const isAllowedOrigin = allowedOrigins.includes(origin);
  // 判断是否为预检请求(OPTIONS 请求)
  const isOptions = request.method === "OPTIONS";

  // 处理预检请求
  if (isOptions) {
    // 构建预检响应的头部信息
    const preflightHeaders = {
      // 如果是允许的源站,则添加 Access-Control-Allow-Origin 头
      ...(isAllowedOrigin && { "Access-Control-Allow-Origin": origin }),
      // 展开其他 CORS 配置选项
      ...corsOptions,
    };

    // 返回预检响应,状态码默认为 200
    return NextResponse.json({}, { headers: preflightHeaders });
  }

  // 处理非预检请求
  const response = NextResponse.next();
  // 为所有响应添加 CORS 头部信息
  Object.entries(corsOptions).forEach(([key, value]) => {
    response.headers.set(key, value);
  });

  return response;
};

// 配置中间件只对 API 路由生效
export const config = {
  matcher: "/api/:path*",
};

五、如何直接响应

我们可以通过返回 ResponseNextResponse 实例直接从中间件进行响应。(此功能自 Next.js v13.1.0 开始可用 )

export const config = {
  matcher: "/api/:function*",
};

export const middleware = (request: NextRequest) => {
  // 鉴权判断
  if (!isAuthenticated(request)) {
    // 返回错误信息
    return new NextResponse(
      JSON.stringify({ success: false, message: "authentication failed" }),
      { status: 401, headers: { "content-type": "application/json" } }
    );
  }
};

http://www.kler.cn/a/610327.html

相关文章:

  • ARCGIS PRO DSK 栅格数据(Raster)
  • SCI一区 | Matlab实现DBO-TCN-LSTM-Attention多变量时间序列预测
  • SpringMVC 配置
  • TensorFlow的数学运算
  • 主流软件工程模型全景剖析
  • JavaScript基础巩固之小游戏练习
  • Node.js 下载安装及环境配置教程、卸载删除环境配置超详细步骤(附图文讲解!) 从零基础入门到精通,看完这一篇就够了
  • .git 文件夹
  • 期权合约作废的话,权利金和保证金会退还么?
  • 两头文件互引问题解决(前置声明)
  • 多源最短路:Floyd算法の暴力美学
  • LeetCode算法题(Go语言实现)_11
  • 31天Python入门——第14天:异常处理
  • DeepSeek V3-0324升级:开启人机共创新纪元
  • 算法模型从入门到起飞系列——递归(探索自我重复的奇妙之旅)
  • AI的未来在手机里!
  • 鸿蒙生态全解析:应用适配分享
  • 2-2 MATLAB鮣鱼优化算法ROA优化CNN超参数回归预测
  • QLoRA和LoRA 微调
  • 01-系统编程