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

Next.js 实战 (十):中间件的魅力,打造更快更安全的应用

什么是中间件?

在 Next.js 中,中间件(Middleware)是一种用于处理每个传入请求的功能。它允许你在请求到达页面之前对其进行修改或响应。

通过中间件,你可以实现诸如日志记录身份验证重定向CORS配置压缩等任务。中间件是构建高效和安全的 web 应用的重要组成部分。

应用场景

身份验证

你可以在中间件中检查用户的身份验证状态,比如从cookie或头部信息中读取JWT令牌,并根据验证结果决定是否允许访问特定页面或API端点。如果验证失败,可以返回401未授权状态码或者重定向到登录页面。
示例代码:

// middleware.js
import { NextResponse } from 'next/server';export function middleware(request) {const token = request.cookies.get('authToken')?.value;if (!token) {// 如果没有令牌,则重定向到登录页面return NextResponse.redirect(new URL('/login', request.url));}// 继续处理链return NextResponse.next();
}

日志记录

中间件非常适合用来记录所有进入应用程序的请求。这可以帮助监控流量模式、诊断问题以及了解用户行为。
示例代码:

// middleware.js
import { NextResponse } from 'next/server';export function middleware(request) {console.log(`Request to ${request.url} at ${new Date().toISOString()}`);// 继续处理链return NextResponse.next();
}

请求/响应转换

可以在请求到达最终目的地之前对请求数据进行预处理,也可以在发送给客户端之前修改响应内容。例如,格式化数据、添加额外的HTTP头、压缩响应体等。
示例代码:

// middleware.js
import { NextResponse } from 'next/server';export async function middleware(request) {// 修改请求体(假设是JSON格式)let modifiedBody = await request.json();modifiedBody.message = "Modified message";// 创建新的请求实例const newReq = new Request(request, {body: JSON.stringify(modifiedBody),});// 获取响应并修改它const response = await fetch(request.nextUrl.pathname, {method: request.method,headers: request.headers,body: newReq.body,});const resClone = await response.clone();const data = await resClone.json();data.newField = "This is a new field"; // 添加新字段// 返回修改后的响应return new Response(JSON.stringify(data), {status: response.status,headers: response.headers,});
}

重定向

基于某些条件(如URL路径、查询参数、用户代理等),你可以使用中间件来执行重定向操作,将用户引导至不同的页面。
示例代码:

// middleware.js
import { NextResponse } from 'next/server';export function middleware(request) {// 如果访问的是旧路径,则重定向到新路径if (request.nextUrl.pathname.startsWith('/login')) {return NextResponse.redirect(new URL('/dashboard', request.url));}// 继续处理链return NextResponse.next();
}

CORS(跨源资源共享)

设置适当的CORS头以允许或限制来自其他域的请求,这对于拥有多个子域名或需要与第三方服务交互的应用非常重要。
示例代码:

// middleware.js
import { NextResponse } from 'next/server';export function middleware(request) {const response = NextResponse.next();// 设置CORS头response.headers.set('Access-Control-Allow-Origin', '*');response.headers.set('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');response.headers.set('Access-Control-Allow-Headers', 'Content-Type, Authorization');return response;
}

限流

防止滥用API接口,可以通过中间件实现速率限制,限制同一IP地址在一定时间内的请求次数。
示例代码:

// middleware.js
import { NextResponse } from 'next/server';
import rateLimit from 'express-rate-limit'; // 需要安装依赖const limiter = rateLimit({windowMs: 1 * 60 * 1000, // 1分钟max: 100, // 每分钟最多100次请求
});export function middleware(request) {return new Promise((resolve, reject) => {limiter(request, {}, (err) => {if (err) {return reject(new NextResponse('Too many requests', { status: 429 }));}resolve(NextResponse.next());});});
}

国际化路由

根据用户的语言偏好或地理位置自动调整网站的语言版本。
示例代码:

// middleware.js
import { NextResponse } from 'next/server';export function middleware(request) {const locale = request.cookies.get('NEXT_LOCALE')?.value || 'en';// 如果不是根路径并且没有包含语言前缀,则添加语言前缀if (!request.nextUrl.pathname.startsWith(`/${locale}`)) {const url = new URL(request.url);url.pathname = `/${locale}${url.pathname}`;return NextResponse.redirect(url);}// 继续处理链return NextResponse.next();
}

静态文件服务

尽管Next.js已经提供了基本的静态文件服务功能,但你可以用中间件来增强这一功能,比如为特定类型的文件提供自定义处理逻辑。
示例代码:

// middleware.js
import { NextResponse } from 'next/server';
import fs from 'fs/promises';export async function middleware(request) {const path = request.nextUrl.pathname;if (path.startsWith('/static-files/')) {try {const filePath = `./public${path}`;const file = await fs.readFile(filePath);return new Response(file, {headers: { 'Content-Type': 'application/octet-stream' },});} catch (error) {return NextResponse.next();}}// 继续处理链return NextResponse.next();
}

config 配置对象

matcher

matcher 是一个非常强大的配置项,它允许你指定中间件应该应用于哪些路径。你可以通过正则表达式或通配符模式来匹配URL路径。

  • 通配符:可以使用 * 来表示任意字符序列。
  • 正则表达式:支持完整的正则表达式语法,但需要使用反斜杠进行转义。
export const config = {matcher: ['/about', '/dashboard/:path*', '/users/:uid'],
};

unstable_ignorePaths

这个配置项可以让中间件忽略某些路径,即不对其应用中间件逻辑。这对于排除不需要处理的资源或者避免循环重定向等问题非常有用。

export const config = {unstable_ignorePaths: ['/api/*', '/static/*'],
};

这里,所有以 /api /开头和静态资源路径都将被忽略,不会受到中间件的影响。

maxDuration

maxDuration 定义了中间件函数的最大执行时间(以秒为单位)。如果中间件执行时间超过了这个值,Next.js将会抛出错误。这有助于防止长时间运行的任务阻塞请求处理。

export const config = {maxDuration: 5, // 中间件最大执行时间为5秒
};

regions

regions 配置项指定了中间件应该部署到的地理区域。这对于希望减少延迟、提高性能的应用来说非常重要,因为它可以让中间件尽可能靠近用户部署。

export const config = {regions: ['us-east-1', 'eu-west-1'], // 在美国东部和欧洲西部部署
};

下面是一个结合了多个config配置项的例子:

// middleware.js
import { NextResponse } from 'next/server';export function middleware(request) {// 中间件逻辑...return NextResponse.next();
}export const config = {matcher: ['/about', '/dashboard/:path*', '/users/:uid'],unstable_ignorePaths: ['/api/*', '/static/*'],maxDuration: 10,regions: ['us-east-1', 'eu-west-1'],
};

总结

总之,Next.js中间件不仅仅是一个简单的请求处理器,它更像是一个构建模块,允许开发者以一种非侵入式的方式对HTTP请求进行预处理和后处理。这不仅简化了代码逻辑,提高了代码的可维护性,而且还有助于创建更加快速、安全和用户友好的Web体验。无论你是刚开始接触Next.js的新手,还是已经熟悉框架的老手,掌握中间件的使用都将为你的项目带来显著的价值。

Github:next-admin

线上预览地址:Next Admin

相关文章:

Next.js 实战 (十):中间件的魅力,打造更快更安全的应用

什么是中间件? 在 Next.js 中,中间件(Middleware)是一种用于处理每个传入请求的功能。它允许你在请求到达页面之前对其进行修改或响应。 通过中间件,你可以实现诸如日志记录、身份验证、重定向、CORS配置、压缩等任务…...

python+playwright自动化测试(四):元素操作(键盘鼠标事件)、文件上传

目录 鼠标事件 悬停 移动 按键 点击 滚轮操作 拖拽 键盘事件 输入文本内容 type输入内容 fill输入内容 按键操作press 文件上传 下拉选/单选框/复选框 滚动条操作 鼠标事件 悬停 page.get_by_text(设置,exactTrue).nth(1).hover() 移动 page.mouse.move(x33…...

【论文+源码】Diffusion-LM 改进了可控文本生成

这篇论文探讨了如何在不重新训练的情况下控制语言模型(LM)的行为,这是自然语言生成中的一个重大开放问题。尽管近期一些研究在控制简单句子属性(如情感)方面取得了成功,但在复杂的细粒度控制(如…...

双目立体校正和Q矩阵

立体校正 对两个摄像机的图像平面重投影,使二者位于同一平面,而且左右图像的行对准。 Bouguet 该算法需要用到双目标定后外参(R,T) 从上图中可以看出,该算法主要分为两步: 使成像平面共面 这个办法很直观&#xff…...

vscode 自用插件

vscode按住ctrl鼠标左键无法跟踪跳转方法名,装这些插件就可以 vscode-elm-jump:常规的代码跳转定义 Vue CSS Peek:跳转css定义 vue-helper:变量函数只跳转定义 Vetur 代码提示 Baidu Comate 自动帮你写console.log Turbo Console Log: ctrl alt l 选中变量之后&am…...

OpenCV:在图像中添加高斯噪声、胡椒噪声

目录 在图像中添加高斯噪声 高斯噪声的特性 添加高斯噪声的实现 给图像添加胡椒噪声 实现胡椒噪声的步骤 相关阅读 OpenCV:图像处理中的低通滤波-CSDN博客 OpenCV:高通滤波之索贝尔、沙尔和拉普拉斯-CSDN博客 OpenCV:图像滤波、卷积与…...

DuckDB:Golang操作DuckDB实战案例

DuckDB是一个嵌入式SQL数据库引擎。它与众所周知的SQLite非常相似,但它是为olap风格的工作负载设计的。DuckDB支持各种数据类型和SQL特性。凭借其在以内存为中心的环境中处理高速分析的能力,它迅速受到数据科学家和分析师的欢迎。在这篇博文中&#xff0…...

MySQL入门(数据库、数据表、数据、字段的操作以及查询相关sql语法)

天行健,君子以自强不息;地势坤,君子以厚德载物。 每个人都有惰性,但不断学习是好好生活的根本,共勉! 文章均为学习整理笔记,分享记录为主,如有错误请指正,共同学习进步。…...

kotlin的协程的基础概念

Kotlin的协程是一种用于简化异步编程的强大工具。 理解协程的基础概念可以帮助开发者有效地利用其能力。 以下是Kotlin协程的一些关键基础概念: 协程(Coroutines) : 协程是一种用于处理并发任务的编程模型,它可以在单…...

Spring--SpringMVC使用(接收和响应数据、RESTFul风格设计、其他扩展)

SpringMVC使用 二.SpringMVC接收数据2.1访问路径设置2.2接收参数1.param和json2.param接收数据3 路径 参数接收4.json参数接收 2.3接收cookie数据2.4接收请求头数据2.5原生api获取2.6共享域对象 三.SringMVC响应数据3.1返回json数据ResponseBodyRestController 3.2返回静态资源…...

隐藏php版本信息x-powered-by

在生产环境中,并不想让别人知道用的是什么版本的php,可以把x-powered-by隐藏掉 在nginx配置文件加上fastcgi_hide_header X-Powered-By; 如下图所示 配置修改后平滑重启nginx...

哈夫曼树(构建、编码、译码)(详细分析+C++代码实现)

D 哈夫曼树 题目要求 编写一个哈夫曼编码译码程序。针对一段文本,根据文本中字符出现频率构造哈夫曼树,给出每个字符的哈夫曼编码,并进行译码,计算编码前后文本大小。 为确保构建的哈夫曼树唯一,本题做如下限定&…...

C++ 二叉搜索树

目录 概念 性能分析 二叉搜索树的插入 二叉树的查找 二叉树的前序遍历 二叉搜索树的删除(重点) 完整代码 key与value的使用 概念 对于一个二叉搜索树 若它的左子树不为空,则左子树上所有的节点的值都小于等于根节点的值若它的右子树不为空…...

docker构建Java项目镜像常用的Java版本,国内私有仓库公网快速下载,解决从docker.io无法下载的问题

2015工作至今,10年资深全栈工程师,CTO,擅长带团队、攻克各种技术难题、研发各类软件产品,我的代码态度:代码虐我千百遍,我待代码如初恋,我的工作态度:极致,责任&#xff…...

低代码系统-氚云、简道云表单控件对比

组件对比 氚云 简道云 是否都有 1 单行文本 单行文本 ☑️ 2 多行文本 多行文本 ☑️ 3 日期 日期时间 ☑️ 4 数字 数字 ☑️ 5 单选框 单选按钮组 ☑️ 6 复选框 复选框组 ☑️ 7 下拉框 下拉框 ☑️ 8 附件 附件 ☑️ 9 图片 图片 ☑️ 10 地址 地…...

为什么IDEA提示不推荐@Autowired❓️如果使用@Resource呢❓️

前言 在使用 Spring 框架时,依赖注入(DI)是一个非常重要的概念。通过注解,我们可以方便地将类的实例注入到其他类中,提升开发效率。Autowired又是被大家最为熟知的方式,但很多开发者在使用 IntelliJ IDEA …...

Unity在WebGL中拍照和录视频

原工程地址https://github.com/eangulee/UnityWebGLRecoder Unity版本2018.3.6f1,有点年久失修了 https://github.com/xue-fei/Unity.WebGLRecorder 修改jslib适配了Unity2021 效果图 录制的视频 Unity在WebGL中拍照和录视频...

爬虫基础之爬取某站视频

目标网址:为了1/4螺口买小米SU7,开了一个月,它值吗?_哔哩哔哩_bilibili 本案例所使用到的模块 requests (发送HTTP请求)subprocess(执行系统命令)re (正则表达式操作)json (处理JSON数据) 需求分析: 视频的名称 F12 打开开发者工具 or 右击…...

mongoDB常见指令

即使我们自己开发用不到mongoDB,但是接手别人项目的时候,别人如果用了,我们也要会简单调试一下 虽然mongoDB用的不是sql语句,但语句的逻辑都是相似的,比如查看数据库、数据表,增删改查这些 我们下面以doc…...

人工智能之深度学习_[5]-神经网络优化学习率衰减优化正则化方法

文章目录 神经网络入门二3 神经网络优化方法3.1 梯度下降算法回顾3.2 反向传播(BP算法)3.2.1 反向传播概念3.2.2 反向传播详解 3.3 梯度下降优化方法3.3.1 指数加权平均3.3.2 动量算法Momentum3.3.3 AdaGrad3.3.4 RMSProp3.3.5 Adam3.3.6 小结 4 学习率衰…...

新手入门指南:基于快马平台构建vmware17交互式安装教学应用

新手入门指南:基于快马平台构建VMware17交互式安装教学应用 作为一个刚接触虚拟化技术的新手,第一次安装VMware Workstation 17时可能会遇到不少困惑。从下载安装包到最终配置完成,整个过程涉及多个步骤,每个环节都可能出现各种问…...

Qwen3.5-9B多场景应用:心理咨询对话记录分析+情绪倾向识别案例

Qwen3.5-9B多场景应用:心理咨询对话记录分析情绪倾向识别案例 1. 项目概述 Qwen3.5-9B是一款拥有90亿参数的开源大语言模型,具备强大的逻辑推理、代码生成和多轮对话能力。该模型特别适合处理心理咨询对话记录分析任务,能够准确识别对话中的…...

赛美特冲刺港股:年营收7亿,刚完成8亿融资,估值73亿

雷递网 雷建平 3月31日赛美特信息集团股份有限公司(简称:“赛美特”)日前更新招股书,准备在港交所上市。赛美特成立以来获得多次融资,其中,2023年4月完成2.33亿元融资,投后估值62.33亿&#xff…...

如何突破Cursor AI使用限制?解锁永久免费Pro功能的终极指南

如何突破Cursor AI使用限制?解锁永久免费Pro功能的终极指南 【免费下载链接】cursor-free-vip [Support 0.45](Multi Language 多语言)自动注册 Cursor Ai ,自动重置机器ID , 免费升级使用Pro 功能: Youve reached you…...

智慧树自动化学习工具终极指南:解放双手,高效完成课程学习

智慧树自动化学习工具终极指南:解放双手,高效完成课程学习 【免费下载链接】fuckZHS 自动刷智慧树课程的脚本 项目地址: https://gitcode.com/gh_mirrors/fu/fuckZHS 智慧树自动化学习工具是一款专为智慧树平台设计的Python脚本,能够帮…...

光流法在气象雷达中的应用:从原理到外推实践

光流法在气象雷达中的应用:从原理到外推实践 气象雷达作为现代气象监测的核心工具,其回波数据蕴含着丰富的天气系统动态信息。如何从这些看似静态的图像序列中提取运动规律,进而预测未来短时内的天气变化,一直是气象学界和工程界关…...

cool-admin(midway版)数据导入模板:Excel模板设计与导出

cool-admin(midway版)数据导入模板:Excel模板设计与导出 【免费下载链接】cool-admin-midway 🔥 cool-admin(midway版)一个很酷的后台权限管理框架,模块化、插件化、CRUD极速开发,永久开源免费,基于midway.js 3.x、typ…...

Hunyuan-MT-7B多语种能力:Pixel Language Portal在联合国六种官方语言互译中的表现

Hunyuan-MT-7B多语种能力:Pixel Language Portal在联合国六种官方语言互译中的表现 1. 引言:当像素冒险遇见多语言翻译 在全球化交流日益频繁的今天,语言障碍仍然是横亘在不同文化之间的无形壁垒。传统翻译工具往往给人冰冷、机械的使用体验…...

若依框架实战:如何优雅地实现静态资源权限校验(附完整代码)

若依框架静态资源权限校验实战指南 在企业级应用开发中,静态资源的安全访问控制是一个常见需求。无论是小程序图片资源管理,还是企业内部文档权限控制,都需要确保只有授权用户才能访问特定资源。本文将深入探讨如何在若依(RuoYi)框架中实现静…...

SpringBoot + MyBatis-Plus项目实战:从零搭建一个JavaEE课程设计骨架(附完整源码结构解析)

SpringBoot MyBatis-Plus项目实战:从零搭建一个JavaEE课程设计骨架(附完整源码结构解析) 当你第一次打开IDE准备开始JavaEE课程设计时,面对空白的项目窗口是否感到无从下手?本文将带你从零开始,用SpringBo…...