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

Next.js 中的中间件

Next.js 中的中间件

Next.js 中的中间件是一个功能强大的工具,允许开发人员拦截、修改和控制应用程序中的请求和响应流。无论我们是构建服务器渲染的网站还是成熟的 Web 应用程序,了解如何有效使用中间件都可以显着增强项目进出的数据流。本文将从基础知识到高级技术探索 Next.js 中的中间件。

什么是中间件?

在构建网络站点或应用程序时,中间件是一个值得理解的重要概念。简单来说中间件是一种提供了拦截和操纵请求 -> 响应周期各个方面的机制。该机制根据应用程序的需求操作传入的请求或传出响应。

Next.js 的中间件允许用户在粒度级别上塑造和控制其 Web 应用程序的行为,而无需额外的步骤,仅此而已。

中间件的工作是在 HTTP 请求和响应通过应用程序时拦截和操作它们。

现在我们了解了基本概念,让我们看一下下面的几个中间件用例。

路由:

路由控制允许将请求重定向到不同的 URL,处理或强制执行 URL 模式。这在管理应用程序中的复杂路由场景时特别有用。

function redirectMiddleware(request) {// 重定向window.location.href = '/new-url';return {status: 204,body: '',};
}

Cookie 管理:

中间件可以管理传入请求和传出响应中的 cookie。这对于设置用户会话 cookie、读取 cookie 进行身份验证或在用户注销时删除 cookie 等任务至关重要。

function cookieManagementMiddleware(request) {const response = {status: 200,cookies: {myCookie: '123',},};return response;
}

鉴权:

中间件可以在授予对特定路由或资源的访问权限之前检查用户是否经过身份验证。

在下面的示例中,当用户尝试访问受保护的路由时,中间件功能通过会话 cookie 检查身份验证来验证其身份。如果用户未通过身份验证,他们将被重定向到登录页面或被拒绝访问。

function authenticationMiddleware(request) {if (!(request.headers.cookie && request.headers.cookie.includes('authenticated=true'))) {// 重定向回登录路由window.location.href = '/login';return {status: 204, // No contentbody: '',};}return {status: 200,};
}

日志

详细记录传入请求,包括请求方法、URL、标头和时间戳信息。这些日志对于诊断问题、跟踪用户活动和分析性能非常宝贵。

function loggingMiddleware(request) {console.log(`Received ${request.method} request to ${request.url} at ${new Date()}`);return {status: 200,};
}

响应定制:

根据特定条件自定义响应头、状态码或响应内容。例如,我们可以设置自定义标头以向客户端提供附加信息或动态调整响应内容。

function customHeadersMiddleware(request) {const response = {status: 200,headers: {'X-Custom-Header': 'Hello, Middleware!',},cookies: {myCookie: '123',},};return response;
}

现在我们了解了中间件是什么以及它为何有用,让我们开始在 Next.js 中使用它。

Next.js 中的中间件

中间件文件

在 Next.js 中,中间件是在项目根目录中通常名为 middleware.ts(或 js) 文件中定义的我们将在该文件中定义中间件函数。这是一个基本的示例函数:

// middleware.ts 
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';export function myMiddleware(request: NextRequest) {// 中间逻辑// ...return NextResponse.next(); // 执行下一个中间件
}

NextResponse

NextResponse 是 Next.js 中的一个 API,允许我们在中间件中处理响应。它提供了重定向请求、重写响应、设置标头、cookie 等方法。

import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';export function myMiddleware(request: NextRequest) {// 将请求重定向到不同的 URLreturn NextResponse.redirect('/new-url');// 重写响应以显示来自不同 URL 的内容return NextResponse.rewrite('/new-content');// 设置响应头和cookieconst response = NextResponse.next();response.headers.set('X-Custom-Header', 'Hello, Middleware!');response.cookies.set('myCookie', '123');return response;
}

在 Next.js 中使用中间件

Next.js 中的中间件函数可以访问传入请求和响应。我们可以修改这些对象来定制应用程序的行为。

import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';export function authenticationMiddleware(request: NextRequest) {// 检查用户是否已通过身份验证if (!request.headers.cookie?.includes('authenticated=true')) {return NextResponse.redirect('/login');}return NextResponse.next(); // 继续下一个中间件或路由处理程序
}

设置 headers 和 Cookie

中间件可以操作传入请求和传出响应中的 headers 和 cookie。这对于自定义响应或管理用户会话等任务非常有用。

import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';export function customHeadersMiddleware(request: NextRequest) {const response = NextResponse.next();response.headers.set('X-Custom-Header', 'Hello, Middleware!');response.cookies.set('myCookie', '123');return response;
}

生成自定义响应

中间件可以通过返回 Response 或 NextResponse 实例直接生成响应。这允许我们根据自定义逻辑控制发送到客户端的响应。

import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';export function customResponseMiddleware(request: NextRequest) {if (/* Some condition */) {return new Response('Custom error message', { status: 400 });}return NextResponse.next();
}

现在我们已经介绍了基础知识,让我们探索一些在 Next.js 中使用中间件的高级技术。

先进的中间件技术

拦截API调用

中间件的一种强大用例是拦截 API 调用。我们可以使用中间件修改 API 请求标头、缓存响应,甚至模拟 API 调用以进行测试。

修改请求头

我们可以使用中间件修改传出 API 请求的标头。这样做通常是为了在发送请求之前将身份验证令牌、API 密钥或其他必要信息添加到标头中。

import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';export function apiInterceptorMiddleware(request: NextRequest) {// 修改请求头request.headers.set('Authorization', 'Bearer myAccessToken');// 可以实现一些api响应缓存逻辑return NextResponse.next();
}

缓存 API 响应

为了提高应用程序的性能,我们可以在中间件中实现 API 响应的缓存。这有助于减少外部 API 的负载并加快对相同数据的后续请求。

import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';export function apiInterceptorMiddleware(request: NextRequest) {// 判断是否存在缓存const cachedResponse = /* 实现缓存逻辑 */;if (cachedResponse) {// 返回缓存return cachedResponse;} else {// 请求const apiResponse = /* 请求逻辑 */;// 缓存响应return apiResponse;}
}

模拟 API 调用进行测试

中间件还可用于在测试期间模拟 API 调用。这可确保我们的测试不依赖于外部服务,从而使测试更加可靠、更快。

import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';export function apiMockMiddleware(request: NextRequest) {if (process.env.NODE_ENV === 'test') {// 在测试环境中返回测试数据return new Response(JSON.stringify({ mockData: true }), {status: 200,headers: {'Content-Type': 'application/json',},});} else {// 在其他环境中继续执行return NextResponse.next();}
}

这些先进技术说明了中间件在处理 Next.js 应用程序中的 API 调用时的灵活性和强大功能。无论我们需要保护 API 请求、通过缓存优化性能,还是通过模拟响应简化测试,中间件都可以成为我们的首选解决方案。

相关文章:

Next.js 中的中间件

Next.js 中的中间件 Next.js 中的中间件是一个功能强大的工具,允许开发人员拦截、修改和控制应用程序中的请求和响应流。无论我们是构建服务器渲染的网站还是成熟的 Web 应用程序,了解如何有效使用中间件都可以显着增强项目进出的数据流。本文将从基础知…...

一、C#笔记

1.注释 /*多行注释*/class HelloWorld{ void Hello(){Console.WriteLine("Hello!");//单行注释}} 2.理解语句 2.1方法、语法、语义 2.2使用标识符 标识符语法规则: 只能使用字母(大写和小写)、数字和下划…...

井盖发生位移怎么办?智能井盖传感器效果

井盖位移是一种严重的安全隐患,因为它可能导致道路受阻并干扰正常的交通,还可能对行人和车辆的安全造成威胁。为了有效应对这一问题,智能井盖传感器的应用提供了一种解决方案。智能井盖传感器可以实时监测井盖的位移情况,并在发现…...

go-zero 开发之安装 goctl 及 go-zero 开发依赖

安装 goctl go 版本在 1.16 及以后执行: GO111MODULEon&&go install github.com/zeromicro/go-zero/tools/goctllatestgo 版本在 1.16 之前执行: GO111MODULEon&&go get -u github.com/zeromicro/go-zero/tools/goctllatest验证是否安…...

win11 CUDA(12.3) + cuDNN(12.x) 卸载

win11 CUDA(12.3) cuDNN(12.x)卸载 信息介绍卸载 信息介绍 本文是对应 win11RTX4070Ti 安装 CUDA cuDNN(图文教程) 的卸载 卸载 控制面板 --> 程序 --> 卸载程序 卸载掉图中红框内的&#xff0c…...

037.Python面向对象_关于抽象类和抽象方法

我 的 个 人 主 页:👉👉 失心疯的个人主页 👈👈 入 门 教 程 推 荐 :👉👉 Python零基础入门教程合集 👈👈 虚 拟 环 境 搭 建 :👉&…...

华为OD机试真题-5G网络建设-2023年OD统一考试(C卷)

题目描述: 现需要在某城市进行5G网络建设,已经选取N个地点设置5G基站,编号固定为1到N,接下来需要各个基站之间使用光纤进行连接以确保基站能互联互通,不同基站之间架设光纤的成本各不相同,且有些节点之间已经存在光纤相连,请你设计算法,计算出能联通这些基站的最小成本…...

【Spring教程25】Spring框架实战:从零开始学习SpringMVC 之 SpringMVC入门案例总结与SpringMVC工作流程分析

目录 1.入门案例总结2. 入门案例工作流程分析2.1 启动服务器初始化过程2.2 单次请求过程 欢迎大家回到《Java教程之Spring30天快速入门》,本教程所有示例均基于Maven实现,如果您对Maven还很陌生,请移步本人的博文《如何在windows11下安装Mave…...

设计模式再探——装饰模式

目录 一、背景介绍二、思路&方案三、过程1.装饰模式简介2.装饰模式的类图3.装饰模式代码4.装饰模式,职责父类拆分的奥义5.装饰模式,部件抽象类的无中生有 四、总结五、升华 一、背景介绍 最近公司在做架构模型的时候,涉及到装饰模式的研…...

【Python必做100题】之第一题(求两数相加)

思路:键盘输入两个数字,求出两个数的和并打印 代码如下: num1 int(input("请输入一个数字:")) num2 int(input("再输入一个数字:")) #求两数相加 result num1 num2 print(f"两数相加的…...

java面试-Dubbo和zookeeper运行原理

远离八股文,面试大白话,通俗且易懂 看完后试着用自己的话复述出来。有问题请指出,有需要帮助理解的或者遇到的真实面试题不知道怎么总结的也请评论中写出来,大家一起解决。 java面试题汇总-目录-持续更新中 分布式注册中心和服务调…...

Rsync+Sersync

服务器相关参数 源服务器 192.168.17.101 目标服务器(同步到的服务器) 192.168.17.103 ##目标服务器配置 ###1、配置rsync服务 1、安装rsync yum -y install rsync 2、配置rsync vim /etc/rsyncd.conf 配置文件内容 uid root gid root use c…...

Leetcode刷题笔记题解(C++):25. K 个一组翻转链表

思路&#xff1a;利用栈的特性&#xff0c;K个节点压入栈中依次弹出组成新的链表&#xff0c;不够K个节点则保持不变 /*** struct ListNode {* int val;* struct ListNode *next;* ListNode(int x) : val(x), next(nullptr) {}* };*/ #include <stack> class Solution { …...

从线性回归到神经网络

目录 一、线性回归关键思想 1、线性模型 2、基础优化算法 二、线性回归的从零开始实现 1、生成数据集 2、读取数据集 3、初始化模型参数 4、定义模型 5、定义损失函数 6、定义优化算法 7、训练 三、线性回归的简洁实现 1、生成数据集 2、读取数据集 3、定义模型…...

LANDSAT_7/02/T1/RAW的Landsat7_C2_RAW类数据集

Landsat7_C2_RAW是指Landsat 7卫星的数据集&#xff0c;采用的是Collection 2级别的数据处理方法&#xff0c;对应的是Tier 1级别的原始数据&#xff08;RAW&#xff09;。该数据集包括了Landsat 7卫星从1999年4月15日开始的所有数据&#xff0c;共涵盖了全球范围内的陆地和海洋…...

绕过360给目标机器添加账户

CS BOF是什么&#xff1f; Beacon 对象文件 (BOF) 是一个已编译的 C 程序&#xff0c;按照约定编写&#xff0c;允许其在 Beacon 进程内执行并使用内部 Beacon API。BOF 是一种通过新的利用后功能快速扩展 Beacon 代理的方法。 BOF 的占地面积较小。它们在 Beacon 进程内部运…...

C/C++ 题目:给定字符串s1和s2,判断s1是否是s2的子序列

判断子序列一个字符串是否是另一个字符串的子序列 解释&#xff1a;字符串的一个子序列是原始字符串删除一些&#xff08;也可以不删除&#xff09;字符&#xff0c;不改变剩余字符相对位置形成的新字符串。 如&#xff0c;"ace"是"abcde"的一个子序…...

Nginx的stream配置

一、stream模块概要。 stream模块一般用于tcp/UDP数据流的代理和负载均衡&#xff0c;可以通过stream模块代理转发TCP消息。 ngx_stream_core_module模块由1.9.0版提供。 默认情况下&#xff0c;没有构建此模块。 -必须使用-with stream配置参数启用。 也就是说&#xff0c;必…...

ubuntu 20.04 server 安装 zabbix

ubuntu 20.04 server 安装 zabbix 参考文档 zabbix没用过&#xff0c;用过prometheus&#xff0c; 因为现在很多应用都支持直接接入prometheus监控&#xff0c; 而且大部分语言都都有sdk支持&#xff0c; 可以直接接入自己的业务数据监控。 https://www.zabbix.com/cn/downlo…...

hive映射es表任务失败,无错误日志一直报Task Transitioned from NEW to SCHEDULED

一、背景 要利用gpt产生的存放在es种的日志表做统计分析&#xff0c;通过hive建es的映射表&#xff0c;将es的数据拉到hive里面。 在最初的时候同事写的是全量拉取&#xff0c;某一天突然任务报错&#xff0c;但是没有错误日志一直报&#xff1a;Task Transitioned from NEW t…...

国防科技大学计算机基础课程笔记02信息编码

1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制&#xff0c;因此这个了16进制的数据既可以翻译成为这个机器码&#xff0c;也可以翻译成为这个国标码&#xff0c;所以这个时候很容易会出现这个歧义的情况&#xff1b; 因此&#xff0c;我们的这个国…...

ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放

简介 前面两期文章我们介绍了I2S的读取和写入&#xff0c;一个是通过INMP441麦克风模块采集音频&#xff0c;一个是通过PCM5102A模块播放音频&#xff0c;那如果我们将两者结合起来&#xff0c;将麦克风采集到的音频通过PCM5102A播放&#xff0c;是不是就可以做一个扩音器了呢…...

数据库分批入库

今天在工作中&#xff0c;遇到一个问题&#xff0c;就是分批查询的时候&#xff0c;由于批次过大导致出现了一些问题&#xff0c;一下是问题描述和解决方案&#xff1a; 示例&#xff1a; // 假设已有数据列表 dataList 和 PreparedStatement pstmt int batchSize 1000; // …...

什么是Ansible Jinja2

理解 Ansible Jinja2 模板 Ansible 是一款功能强大的开源自动化工具&#xff0c;可让您无缝地管理和配置系统。Ansible 的一大亮点是它使用 Jinja2 模板&#xff0c;允许您根据变量数据动态生成文件、配置设置和脚本。本文将向您介绍 Ansible 中的 Jinja2 模板&#xff0c;并通…...

HashMap中的put方法执行流程(流程图)

1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中&#xff0c;其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下&#xff1a; 初始判断与哈希计算&#xff1a; 首先&#xff0c;putVal 方法会检查当前的 table&#xff08;也就…...

【从零学习JVM|第三篇】类的生命周期(高频面试题)

前言&#xff1a; 在Java编程中&#xff0c;类的生命周期是指类从被加载到内存中开始&#xff0c;到被卸载出内存为止的整个过程。了解类的生命周期对于理解Java程序的运行机制以及性能优化非常重要。本文会深入探寻类的生命周期&#xff0c;让读者对此有深刻印象。 目录 ​…...

TSN交换机正在重构工业网络,PROFINET和EtherCAT会被取代吗?

在工业自动化持续演进的今天&#xff0c;通信网络的角色正变得愈发关键。 2025年6月6日&#xff0c;为期三天的华南国际工业博览会在深圳国际会展中心&#xff08;宝安&#xff09;圆满落幕。作为国内工业通信领域的技术型企业&#xff0c;光路科技&#xff08;Fiberroad&…...

【技巧】dify前端源代码修改第一弹-增加tab页

回到目录 【技巧】dify前端源代码修改第一弹-增加tab页 尝试修改dify的前端源代码&#xff0c;在知识库增加一个tab页"HELLO WORLD"&#xff0c;完成后的效果如下 [gif01] 1. 前端代码进入调试模式 参考 【部署】win10的wsl环境下启动dify的web前端服务 启动调试…...

02-性能方案设计

需求分析与测试设计 根据具体的性能测试需求&#xff0c;确定测试类型&#xff0c;以及压测的模块(web/mysql/redis/系统整体)前期要与相关人员充分沟通&#xff0c;初步确定压测方案及具体的性能指标QA完成性能测试设计后&#xff0c;需产出测试方案文档发送邮件到项目组&…...

FMC STM32H7 SDRAM

如何无痛使用片外SDRAM? stm32 已经成功初始化了 STM32H7 上的外部 SDRAM&#xff08;32MB&#xff09; 如何在开发中无痛使用SDRAM 使它像普通 RAM 一样“自然地”使用? [todo] 重要 MMT(Memory Management Tool) of STM32CubeMx The Memory Management Tool (MMT) disp…...