中间件是什么?什么场景使用?

🥷 一、什么是中间件?

中间件就像一条跑道上的检查点

  • 选手(请求 request)跑进来 → 先经过几个检查点(中间件)
  • 每个检查点都可以干点事:查身份证(鉴权)、量血压(数据校验)、拍个照(日志)
  • 最后才到达终点(业务逻辑 Controller)

👉 所以:中间件 = 在请求到达核心逻辑之前/之后插入的一段可复用的小程序


🚦 二、适用场景

中间件特别适合解决"通用但非业务"的问题(专业说法叫 横切关注点 cross-cutting concerns)。

常见的场景有:

  1. 安全保镖类 🛡️

    • 登录校验、权限验证
    • 限流(防止一个人疯狂刷接口)
  2. 服务员类 🍽️

    • 给数据配套餐具(格式化响应,比如统一返回 { code, data, message }
    • CORS 处理(跨域服务)
  3. 记录员类 📒

    • 日志打印(谁在什么时候访问了什么接口)
    • 性能监控(统计耗时)
  4. 修理工类 🔧

    • 捕获错误,统一返回用户友好的信息
    • 请求数据预处理(比如 JSON → 对象,表单 → 参数)

💻 三、代码举例(Express 中间件)

用 Node.js 的 Express 举例,超级直观:

scss 复制代码
const express = require('express');
const app = express();

// 1️⃣ 日志中间件:像"监控摄像头"
function logger(req, res, next) {
  console.log(`[LOG] ${req.method} ${req.url}`);
  next(); // 🚦 放行,交给下一个中间件
}

// 2️⃣ 鉴权中间件:像"门口保安"
function auth(req, res, next) {
  if (!req.headers.authorization) {
    return res.status(401).json({ message: '❌ 未授权' });
  }
  console.log('✅ 授权通过');
  next();
}

// 3️⃣ 统一响应格式中间件:像"餐厅出菜时统一装盘"
function formatResponse(req, res, next) {
  // 重写 res.send 方法
  const oldSend = res.send;
  res.send = function (data) {
    oldSend.call(res, {
      code: 0,
      message: 'success',
      data: data
    });
  };
  next();
}

// 注册中间件(顺序很重要!)
app.use(logger);
app.use(auth);
app.use(formatResponse);

// 核心业务逻辑
app.get('/hello', (req, res) => {
  res.send({ greeting: 'Hello Middleware!' });
});

app.listen(3000, () => {
  console.log('🚀 Server running on http://localhost:3000');
});

执行流程

👉 请求 GET /hello 时:
logger → auth → formatResponse → /hello 控制器 → formatResponse 加工响应 → 返回客户端

就像一条流水线,每个工人(中间件)负责一道工序。


🎯 四、总结

  • 定义:中间件就是请求和业务之间的"拦截器 + 工具人",负责做通用的脏活累活。
  • 适用场景:日志、鉴权、数据预处理、错误捕获、统一响应、跨域......这些和业务没直接关系,但又少不了的地方。
  • 核心价值:让业务逻辑更干净,通用逻辑可复用,可插拔。

流程图(请求 → 多个中间件 → 控制器 → 响应) ,更直观地看到中间件像是"安检流程"的感觉 这就是中间件的流程图 🖼️:

明白啦 👍

我直接给你画出一张清晰的中间件执行流程图(请求和响应都有):

vbscript 复制代码
          ┌───────────────┐
          │   请求 Request │
          └───────┬───────┘
                  │
                  ▼
        ┌─────────────────┐
        │  中间件① 日志    │
        └───────┬─────────┘
                  │
                  ▼
        ┌─────────────────┐
        │  中间件② 鉴权    │
        └───────┬─────────┘
                  │
                  ▼
        ┌────────────────────┐
        │  中间件③ 格式化响应 │
        └───────┬────────────┘
                  │
                  ▼
        ┌───────────────────┐
        │   业务逻辑 Controller │
        └───────┬───────────┘
                  │
         (执行业务并生成响应)
                  │
                  ▼
        ┌────────────────────┐
        │  中间件③ 格式化响应 │
        └───────┬────────────┘
                  │
                  ▼
        ┌─────────────────┐
        │  中间件② 鉴权    │
        └───────┬─────────┘
                  │
                  ▼
        ┌─────────────────┐
        │  中间件① 日志    │
        └───────┬─────────┘
                  │
                  ▼
          ┌───────────────┐
          │   响应 Response │
          └───────────────┘

🔵 ①->③ 方向:请求进来时依次经过各个中间件 → 业务逻辑。

🔴 ③->① 方向:响应出来时再倒序经过中间件 → 返回给客户端。

这样可以看到中间件不仅能预处理请求 ,还能后处理响应

相关推荐
半夏知半秋17 小时前
rust学习-闭包
开发语言·笔记·后端·学习·rust
LucianaiB17 小时前
【保姆级教程】10分钟把手机变成AI Agent:自动刷课、回消息,学不会我“退网”!
后端
Mr -老鬼17 小时前
功能需求对前后端技术选型的横向建议
开发语言·前端·后端·前端框架
IT=>小脑虎17 小时前
Go语言零基础小白学习知识点【基础版详解】
开发语言·后端·学习·golang
Eric_见嘉18 小时前
NestJS 🧑‍🍳 厨子必修课(九):API 文档 Swagger
前端·后端·nestjs
a程序小傲18 小时前
小红书Java面试被问:TCC事务的悬挂、空回滚问题解决方案
java·开发语言·人工智能·后端·python·面试·职场和发展
短剑重铸之日18 小时前
《SpringBoot4.0初识》第五篇:实战代码
java·后端·spring·springboot4.0
jump_jump19 小时前
SaaS 时代已死,SaaS 时代已来
前端·后端·架构
a努力。19 小时前
国家电网Java面试被问:最小生成树的Kruskal和Prim算法
java·后端·算法·postgresql·面试·linq
superman超哥19 小时前
Rust Vec的内存布局与扩容策略:动态数组的高效实现
开发语言·后端·rust·动态数组·内存布局·rust vec·扩容策略