朝阳博客

  • Article
  • Project
  • HTML+CSS
  • Bootstrap
  • JavaScript
  • jQuery
  • PHP
  • Java
  • Linux
  • MySQL
朝阳博客
一款专注于博客的响应式网站
  1. 首页
  2. 未分类
  3. 正文

Node.js 中间件

2026年3月17日 1点热度 0人点赞 0条评论
本文将以 **Node.js 中间件封装** 为主题,从 **原理 → 设计 → 封装模式 → 实战示例 → 工程化建议**
系统讲解中间件的正确使用方式。

一、什么是 Node.js 中间件?

一句话理解

**中间件就是夹在“请求”和“响应”之间的一层可复用逻辑**
Request
↓
Middleware A
↓
Middleware B
↓
Business Logic
↓
Response

中间件解决什么问题?

  • 日志
  • 鉴权
  • 限流
  • 参数校验
  • 错误处理
  • 性能监控
👉 **与业务无关,却必须存在的能力**

二、中间件的设计核心思想

  • 解耦
  • 复用
  • 可组合
  • 可配置

中间件的 4 个基本原则

  1. 单一职责
  2. 无业务状态
  3. 可插拔
  4. 可组合

三、Koa / Express 中间件模型对比

Express 中间件

(req, res, next) => { }
基于回调
线性执行

Koa 中间件(洋葱模型)

async (ctx, next) => {    await next();}
→ 进入
→→→
←←←
← 返回
非常适合做“前后拦截”逻辑

四、中间件封装的基本模板(Koa 示例)

标准中间件结构

function middleware(options) {    return async function (ctx, next) {        // 前置逻辑        await next();        // 后置逻辑    };}

为什么要用「工厂函数」?

可配置
可复用
易测试

五、实战一:日志中间件封装

需求

记录请求耗时
不侵入业务

封装实现

function logger() {    return async (ctx, next) => {        const start = Date.now();        await next();        const cost = Date.now() - start;        console.log(            [</span><span class="code-snippet__string"><span class="code-snippet__subst">${ctx.method}</span></span><span class="code-snippet__string">] </span><span class="code-snippet__string"><span class="code-snippet__subst">${ctx.url}</span></span><span class="code-snippet__string"> - </span><span class="code-snippet__string"><span class="code-snippet__subst">${cost}</span></span><span class="code-snippet__string">ms        );    };}

使用

app.use(logger());

六、实战二:统一错误处理中间件

为什么必须封装?

避免 try/catch 满天飞
保证响应格式统一

封装示例

function errorHandler() {    return async (ctx, next) => {        try {            await next();        } catch (err) {            ctx.status = err.status || 500;            ctx.body = {                code: ctx.status,                message: err.message            };        }    };}

放置位置(非常重要)

app.use(errorHandler());
必须是第一个中间件

七、实战三:鉴权中间件封装

封装目标

解耦业务
提前拦截非法请求

示例实现

function auth() {    return async (ctx, next) => {        const token = ctx.headers.authorization;        if (!token) {            ctx.throw(401, '未登录');        }        ctx.state.user = verifyToken(token);        await next();    };}

八、实战四:限流中间件(Redis)

典型「工程级中间件」

function rateLimit({ max, window }) {    return async (ctx, next) => {        const key = rate:</span><span class="code-snippet__string"><span class="code-snippet__subst">${ctx.ip}</span></span><span class="code-snippet__string">;        const count = await redis.incr(key);        if (count === 1) {            await redis.expire(key, window);        }        if (count > max) {            ctx.status = 429;            ctx.body = '请求过于频繁';            return;        }        await next();    };}

九、中间件的组合与执行顺序

执行顺序示例

app.use(errorHandler());app.use(logger());app.use(auth());app.use(rateLimit());app.use(router.routes());

顺序设计原则

类型 放置位置
错误处理 最前
日志 / 监控 靠前
鉴权 路由前
业务 最后

十、如何写「高质量中间件」?

Checklist

✅ 是否只做一件事
✅ 是否无业务耦合
✅ 是否可配置
✅ 是否有默认值
✅ 是否能独立测试

十一、中间件工程化目录结构建议

middlewares/    ├─ auth.js    ├─ logger.js    ├─ rateLimit.js    ├─ errorHandler.js    └─ index.js
// index.jsmodule.exports = {    auth,    logger,    rateLimit,    errorHandler};

十二、常见反模式(一定要避免)

❌ 中间件里写业务逻辑
❌ 中间件修改大量 ctx.body
❌ 中间件依赖数据库事务
❌ 中间件顺序混乱

十三、总结

Node.js 中间件封装的本质是:把“横切关注点”从业务中剥离出来。
一句话总结:
业务专注做业务
中间件专注做能力
架构才会清晰、可维护、可扩展

标签: 暂无
最后更新:2026年3月17日

aiyao

你要加油,你喜欢的人还没结婚。

点赞
< 上一篇
下一篇 >

文章评论

razz evil exclaim smile redface biggrin eek confused idea lol mad twisted rolleyes wink cool arrow neutral cry mrgreen drooling persevering
取消回复

COPYRIGHT © 2021 zhaoyangweb.com. ALL RIGHTS RESERVED.

Theme Kratos Made By Seaton Jiang

冀ICP备2021020018号-1