中间件详解与自定义 - 实践

news/2025/10/1 22:32:55/文章来源:https://www.cnblogs.com/ljbguanli/p/19123004

中间件详解与自定义 - 实践

引言:中间件——Express.js的链式魔力与扩展引擎

欢迎继续《Node.js 服务端开发》专栏的第三个模块!在上篇文章《Express路由设计最佳实践》中,我们探讨了GET/POST/PUT/DELETE路由、参数提取和嵌套路由的精髓,帮助你构建结构化的RESTful API。现在,让我们聚焦Express.js的核心扩展机制:中间件(Middleware)。中间件是Express的灵魂,它允许在请求-响应周期中插入自定义逻辑,如日志、认证或解析body,实现插件化开发,而无需修改核心代码。

随着Node.js Current版本24.8.0的成熟和LTS版本22.19.0 'Jod’的稳定,Express.js v5.1.0(于2025年3月31日发布)进一步强化了中间件系统:引入了官方LTS时间表,确保v5系列的长期维护,并优化了异步中间件的性能,支持Node 24的实验性async hooks。 这个版本内置了更多默认中间件,并强调错误处理的标准化。 本文将详解内置中间件(如body-parser的现代替代)、错误处理中间件、顺序执行与next()机制。我们将结合历史演进、代码示例、性能分析和2025年的最佳实践(如小而专注的函数和异步支持),提供深度洞见。

中间件概念源于Connect框架(Express的前身,2010年),Express从v1起继承并扩展它。 到v4(2014),Express移除部分内置中间件(如body-parser),要求单独安装;v5.1.0则重新内置关键功能,并优化了链式执行。 为什么中间件关键?它使Express从简单路由器变为全功能框架,支持数百万生产应用。 在2025年,中间件趋势强调模块化和安全性,如集成OpenTelemetry追踪。 假设你有基本Express app,让我们从机制入手,逐步自定义。

中间件基础:顺序执行与next()机制

中间件是函数,接收req(请求)、res(响应)和next(下一个函数),形成链式管道。Express按注册顺序执行它们,next()传递控制。

next()机制详解

next()是回调,调用它推进链;不调用则链停止(用于结束响应)。

基本示例(app.js):

const express = require('express');
const app = express();
app.use((req, res, next) => {
console.log('Middleware 1: Logging request');
next();  // 继续
});
app.use((req, res, next) => {
if (req.query.token !== 'secret') {
return res.status(401).send('Unauthorized');  // 停止链
}
next();  // 授权通过
});
app.get('/', (req, res) => res.send('Hello'));

深度剖析:中间件栈是数组,Express迭代调用,每个next触发下一个。 next(‘route’)跳过剩余中间件到下一个路由;next(err)触发错误链。 历史:v3引入async next支持,v5.1.0优化了栈溢出防护。

顺序执行的最佳实践

  • 注册顺序:通用(如日志)在前,特定(如认证)在中,路由最后。
  • 异步支持:用async函数,await后next()。
    示例异步:
app.use(async (req, res, next) => {
try {
const data = await fetchData();
req.data = data;
next();
} catch (err) {
next(err);  // 传err到错误链
}
});

深度:异步不阻塞事件循环,但顺序仍线性。 性能:过多中间件增延迟;2025年v5.1.0的并行实验(实验性)允许非依赖中间件并发。 误区:忘记next()导致超时;用Clinic.js诊断链瓶颈。

内置中间件:body-parser的演进与其他

Express v5.1.0内置关键中间件,简化配置。body-parser曾是独立包,现整合为express.json()等。

body-parser详解(现代替代)

用于解析请求体。

示例:

app.use(express.json({ limit: '50mb' }));  // JSON body
app.use(express.urlencoded({ extended: true }));  // form数据

深度:express.json()解析application/json,limit防DoS。 extended: true用qs库支持嵌套对象。 历史:v4移除body-parser,v4.16内置express.json。 v5.1.0添加了自动压缩支持。

其他内置:

  • express.static:静态文件(如上文)。
  • express.raw():原始buffer body。

最佳实践:仅POST/PUT用body解析;验证body防无效负载。

错误处理中间件:四参数的守护者

错误中间件处理链中抛出的err,有四个参数:(err, req, res, next)。

示例:

app.use((err, req, res, next) => {
console.error(err.stack);
res.status(500).json({ error: 'Internal Server Error' });
});

深度:放链尾;Express默认处理器在v5.1.0更智能,发送HTML/JSON根据Accept。 next(err)触发它。 历史:v2引入,v5增强了自定义错误类支持。

最佳实践:分类err(如if (err.status) res.status(err.status));生产隐藏stack。 2025:集成Sentry日志。

自定义中间件:从小函数到强大扩展

自定义中间件是函数或闭包。

示例认证:

function authMiddleware(req, res, next) {
if (!req.headers.authorization) {
return next(new Error('Unauthorized'));  // 传err
}
// 验证...
next();
}
app.use(authMiddleware);

深度:工厂函数返回中间件,如logMiddleware(level) => (req,res,next)=>…。 性能:保持小,避免重计算。 最佳实践:测试隔离;2025用TypeScript泛型类型化。

高级主题:优化与2025趋势

  • 条件中间件:app.use(‘/admin’, authMiddleware)。
  • 第三方:morgan日志、helmet安全。
  • 2025优化:v5.1.0的中间件缓存,减少重复执行。 趋势:AI生成中间件,WebAssembly插件。

表格总结最佳实践:

实践理由与示例
小而专注每个中间件一责,易测试/复用。
错误传递用next(err)统一处理。
顺序管理日志前、认证中、路由后。
异步处理try-catch + next(err)。

结语:中间件,Express的无限扩展

通过内置如body-parser替代、错误处理、顺序与next(),你已掌握Express v5.1.0中间件的深度。 从Connect起源,到2025的异步优化,它让你的API更健壮。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/924348.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

格林达姆 花——季护航2006年-2017年天朝纸媒资料备份(不全)

补充:由于B站的P主@答脸P 在网易云音乐的鉴---证歌曲播放量即将破万的时候答脸P网易音乐人账号喜提永封,以及流浪的猎人在多个QQ群发布2015年文X部120首禁曲之一的,由洛天依演唱的“腐乘以无限大”曲谱导致流浪的猎…

【Groovy】变量和基本数据类型

1 变量 ​ 1)变量的声明 int a = 1 def b def c = 1​ 在脚本中定义变量无需声明变量的类型,如下。在类不能使用以下方式定义变量,否则会编译报错。 a = 1 b = "abc"​ 2)变量命名规范变量名可…

免费网站空间 asp.net东莞市视频直播网站开发

💌 所属专栏:【Git】 😀 作  者:我是夜阑的狗🐶 🚀 个人简介:一个正在努力学技术的CV工程师,专注基础和实战分享 ,欢迎咨询! 💖 欢迎大…

2026届模拟/射频IC设计方向保研经验分享

2026届模拟/射频IC设计方向保研经验分享保研经验分享 1. 前言 以下内容都是个人经历,可能带有主观性,仅供参考。禁止开盒。2. 个人背景学校:西安电子科技大学专业:微电子科学与工程(教改班)排名:班级 2/30,专业…

2021 ICPC 沈阳 BEFHJLM(待补

B - Bitwise Exclusive-OR Sequence 种类并查集。 根据每一对的异或关系,可以得到二进制中每一位是否互斥关系,涉及到两种关系的处理用种类并查集更好维护;另外再维护两个点之间是否有关系,之后可能形成多个关系的…

贵州公司网站开发西宁最好网站建设公司哪家好

你可能知道while除了表示“当……的时候”,还有它与when, as的用法区别,但是这些还不够全面,今天小编就来给大家详细解析一下相关的用法,一起来看看吧!一、考查表示时间的用法,其意为“当……的时候”。如&…

Docker容器完全操控指南

Docker容器完全操控指南pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", &qu…

【Groovy】Groovy环境搭建

1 前言 ​ Groovy 是一种基于 JVM 平台的敏捷且动态的编程语言,能与 Java 无缝集成。该语言由 James Stracham 和 Bob McWhirter 于 2003 年启动开发,在 2007 年 1 月发布第一个版本。 ​ Groovy 具有以下优势…

php 网站 发布优对 网站开发

摘要:沈海军:今天(2019年4月10日)下午接受广东卫视采访,就晚上21:00即将发布的人类首张黑洞照片发表了评论。提笔撰稿时,尚未到照片官方的发布时间,故不能一睹黑洞照片的芳容,但鉴于…

做网站分页垦利网站定制

# -*- coding: utf-8 -*- z0 def numbersize(a,b):global zif(a>b):zaelif(a<b):zbelif(ab):zaelse:z99return z

2025年TAB拉链制造商权威推荐榜:创新设计与耐用品质口碑

2025年TAB拉链制造商权威推荐榜:创新设计与耐用品质口碑 在纺织辅料行业快速发展的今天,TAB拉链作为功能性与装饰性并重的重要配件,其技术创新与品质标准已成为衡量制造商实力的关键指标。随着新材料应用与智能制造…

变量类型

isinstance() isinstance(object, classinfo) 是一个 Python 内置函数,用于判断一个对象 (object) 是否是某个类或其子类的实例,或者是否属于 classinfo 参数指定的类型或元组中的一种类型。它返回 True 或 False,并…

VMware Cloud Foundation 9.0.1.0 发布 - 领先的多云平台

高效管理虚拟机 (VM) 和容器工作负载,为本地部署的全栈超融合基础架构 (HCI) 提供云的优势。VMware Cloud Foundation 9.0.1.0 发布 - 领先的多云平台 高效管理虚拟机 (VM) 和容器工作负载,为本地部署的全栈超融合基…

velero 备份及使用方法

1、安装velero wget https://github.com/vmware-tanzu/velero/releases/download/v1.17.0/velero-v1.17.0-linux-amd64.tar.gz tar -xzf velero-v1.17.0-linux-amd64.tar.gz cd velero-v1.17.0-linux-amd64 cp velero…

CT5132 Program. Tools for AI:-week4 note

CT5132 Program. & Tools for AI:-week4 noteNumpy: Multidimensional Arrays and Fancy Indexing 标题解析:NumPy: Multidimensional Arrays and Fancy Indexing 🧠 NumPy 是什么? NumPy(Numerical Python)…

Fluttercon EU 2025 :Let‘s go far with Flutter - 详解

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

洛谷月赛T1 P14081 「CZOI-R7」炸弹游戏

洛谷月赛T1 P14081 「CZOI-R7」炸弹游戏竟然做了一晚上才AC 发题解警示自己犯糖 一道思维题,推公式即可首先手玩一下样例发现 m=1,m=2均无法成功,直接输出 如果大于2一定存在范围[L,R]可以胜利 对于最小值,不难想…

io的异步处理io_uring,实现io_uring_tcp_server - 详解

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

网络舆情应对措施seo推广教程seo推广技巧

1、什么是多态性&#xff1f;什么是虚拟方法调用&#xff1f; 对象的多态性&#xff1a; Person p new xx(); 此时new的对象可以为多种形态&#xff0c;但需要是person类的子类。即父类的引用指向子类的对象。 虚拟方法调用: p.eat(); 该语句在编译时会认为时调用Person类中的…

VMware NSX 4.2.3.1 发布,新增功能概览

VMware NSX 4.2.3.1 - 网络安全虚拟化平台VMware NSX 4.2.3.1 发布,新增功能概览 VMware NSX 4.2.3.1 - 网络安全虚拟化平台 构建具有网络连接和安全性的云智能网络,跨多种云环境支持一致的策略、运维和自动化。 请访…