Express 入门指南(三) 中间件(Middleware)

一、中间件本质与作用

  1. 定义

    >中间件是能访问请求对象(req)、响应对象(res)和下一个中间件函数(next)的函数,用于预处理请求或后处理响应。
    >类比“加工流水线”,请求从进入服务器到返回响应的过程中会经过多个中间件处。‌

  2. 核心功能

    >执行任意代码(如日志记录、数据验证)
    >修改req/res对象(如添加自定义属性)
    >终止请求-响应循环(如res.send()直接返回)或调用next()传递控制权 

二、中间件类型与用法 

    1.应用级中间件

        >通过app.use()全局生效,或绑定到特定HTTP方法(如app.get()

app.use((req, res, next) => {
   console.log('全局中间件');
   next();
});

     2.路由级中间件

        >绑定到express.Router()实例,仅对特定路由生效

const router = express.Router();
router.use('/api', (req, res, next) => { ... });

     3.错误处理中间件

        >需包含4个参数(err, req, res, next),用于捕获异常

 app.use((err, req, res, next) => {
    console.error(err.stack);
    res.status(500).send('服务器错误');
 });

     4.内置与第三方中间件

        >内置:如express.json()解析JSON请求体。

        >第三方:如body-parser(现已被Express内置替代)

三、关键注意事项

     1.next()调用

       若中间件未终止请求(如未调用res.send()),必须调用next()传递控制权,否则请求会挂起

     2. 执行顺序

        >中间件按注册顺序执行,需合理排列(如日志中间件应优先于路由)

    3.错误处理优先级

      >错误中间件需定义在最后,确保能捕获所有前置中间件的异常

四、典型应用场景

     1.日志记录

app.use((req, res, next) => {
  console.log(`${req.method} ${req.url}`);
  next();
});

    2.身份验证

app.use('/admin', (req, res, next) => {
  if (req.headers.token === 'secret') next();
  else res.status(403).send('无权访问');
});

   3.静态文件服务

app.use(express.static('public'));

五、重点说下中间件执行顺序

Express 中间件的执行顺序是框架的核心机制之一,理解它对构建可靠应用至关重要。以下是核心规则和实际示例:

核心执行规则

  1. 注册顺序即执行顺序

    >中间件按照 app.use() 或路由方法(app.get() 等)的‌代码书写顺序‌依次执行
    >类似‌流水线处理‌,请求依次通过每个中间件
  2. next() 控制权传递

    >调用 next() 将控制权交给‌下一个中间件
    >不调用 next() 将终止请求处理链
  3. 响应发送即终止

    >任何中间件执行 res.send()res.json() 等响应方法后,后续中间件‌不会执行
     

关键执行流程图示 

 graph LR
A[请求进入] --> B[中间件1]
B -- next() --> C[中间件2]
C -- next() --> D[路由处理器]
D -- res.send() --> E[响应返回]
C -- 未调用next --> F[流程终止]

典型执行场景示例

场景1:基础顺序控制

app.use((req, res, next) => {
  console.log('第一层中间件');
  next(); // 必须调用next传递控制权
});

app.use((req, res, next) => {
  console.log('第二层中间件');
  next();
});

app.get('/', (req, res) => {
  res.send('最终响应'); // 终止流程
});

// 访问 '/' 的输出顺序:
// 第一层中间件 → 第二层中间件 → 最终响应

场景2:路由级中间件顺序

// 全局中间件
app.use((req, res, next) => {
  console.log('全局中间件');
  next();
});

// 路由专属中间件
app.use('/api', (req, res, next) => {
  console.log('API路由中间件');
  next();
});

// 路由处理器
app.get('/api/data', (req, res) => {
  res.json({ data: 'test' });
});

// 访问 '/api/data' 的输出:
// 全局中间件 → API路由中间件 → 路由处理器

场景3:错误处理中间件(必须最后注册)

// 常规中间件
app.get('/error', (req, res, next) => {
  next(new Error('测试错误')); // 主动触发错误
});

// 错误处理中间件(4个参数)
app.use((err, req, res, next) => { 
  console.error('错误处理:', err.message);
  res.status(500).send('服务器错误');
});

// 访问 '/error' 的流程:
// 路由处理器 → 错误处理中间件

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值