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

🥷 一、什么是中间件?

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

  • 选手(请求 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 │
          └───────────────┘

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

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

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

相关推荐
胡写代码3 分钟前
雪花 ID 传到前端就变了个数?我用全局 Long 转 String 一次收口
前端·后端
SimonKing5 分钟前
一只离线鼠鼠,干翻了一堆在线格式转换网站
java·后端·程序员
武子康7 分钟前
两台 A6000,LingBot 应该先验哪条路径?
人工智能·后端·agent
Thneonl13 分钟前
值班第一年:最先要学的不是排障,是叫人
后端·程序员
codigger14 分钟前
Redis 正式接入 AI:当"最懂速度的数据库"开始解决"记忆问题"
redis·分布式·后端·ai·向量检索
沐言人生16 分钟前
82.4k 星!把十几万行代码变成知识图谱,新人终于不用硬啃了
前端·后端·github
Thneonl16 分钟前
让 LLM 值第一班岗:只读的活放手交,变更的活一条别给
后端·架构
挖掘狂人35 分钟前
Redis 正式接入 AI:当"最懂速度的数据库"开始解决"记忆问题"
人工智能·redis·后端
皓月盈江41 分钟前
Go读写TXT文件
开发语言·后端·golang·go·读写txt文件·bufio·go读写txt
hsfxuebao43 分钟前
Hermes Agent进化篇:Skills、Hooks、Plugins、Cron
人工智能·后端