Node.js Express 中间件实现原理与源码解析

作者:接口漫谈时间:2026-10-25 21:32:04浏览:241

本文深入解析 Node.js Express 框架中中间件的实现机制。通过源码分析,阐述中间件作为无路由表 Layer 的核心概念,详解 use 方法对默认路径的处理逻辑,以及 handle 方法中基于 route 属性的分发策略。文章结合具体代码片段,展示如何区分处理中间件与路由,帮助开发者理解 Express 请求处理流程。

先看应用

应用规则:

  • 在 Express 框架中,use 方法的第一个参数用于指定匹配路径;若未传递该参数,则默认视为匹配根路径“/”。
  • 中间件的匹配机制采用惰性匹配策略。例如,配置了匹配路径为 /a 的中间件,当访问路径 /aa 时,该中间件同样会被执行。这一特性意味着,如果调用 use 时不指定匹配路径,该中间件将应用于所有请求。
const express = require("./express");
const app = express();
// 第一个参数是匹配路径 不传相当于"/"
app.use(function (req, res, next) {
  req.a = 1;
  next();
});
app.use("/", function (req, res, next) {
  req.a++;
  next();
});
app.get("/", function (req, res, next) {
  res.end(req.a + "");
});
app.use("/a", function (req, res, next) {
  req.a++;
  next();
});
app.get("/a", function (req, res, next) {
  res.end(req.a + "");
});
app.listen(3000);

先看应用

实现思路

结合之前的路由实现原理,中间件本质上是一个“没有路由表”的 Layer 对象。实现的关键在于:

  • 在订阅监听阶段,需对“未传递匹配路径”等特殊情况进行处理。
  • 在请求分发阶段,需根据 Layer 对象“是否具有路由表 route 属性”进行判断,从而对中间件进行区分处理。

通过以上步骤即可实现中间件功能。

具体实现

订阅监听时做下对“不传匹配路径”等情况的处理

定义 use 方法

Router.prototype.use = function (path, ...handlers) {
  if (!handlers[0]) {
    // 只传递了一个函数
    handlers.push(path); // app.use(function(){})  app.use()
    path = "/";
  }
  handlers.forEach((handler) => {
    let layer = new Layer(path, handler);
    layer.route = undefined; // 不写也是 undefined , 主要告诉你 中间件没有 route
    this.stack.push(layer);
  });
};

在请求发布时,根据 Layer 对象“是否具有路由表 route 属性”进行判断,从而对中间件进行区分处理。

改写 handle 方法

Router.prototype.handle = function (req, res, done) {
  let { pathname } = url.parse(req.url);
  let method = req.method.toLowerCase();
  let idx = 0;
  const next = (err) => {
    // 中间件 和内部的 next 方法 出错都会走这个 next
    if (idx >= this.stack.length) return done(); // 路由处理不了 传递给应用层
    let layer = this.stack[idx++];
    // 无论是路由还是中间件 前提是路径必须匹配
    if (layer.match(pathname)) {
      // match 还没有更改
      if (!layer.route) {
        // 没有说明是中间件   注意 此处就是对中间件的区分处理
        layer.handle_request(req, res, next); // 直接执行中间件函数
      } else {
        // 路由必须匹配方法
        if (layer.route.methods[method]) {
          // 这个 next 可以让路由层扫描下一个 layer
          layer.handle_request(req, res, next); // route.dispatch
        } else {
          next();
        }
      }
    } else {
      next();
    }
  };
  next(); // 请求来了取出第一个执行
};

总结流程

先看应用

以上就是 Node.js Express 实现中间件的详细内容,更多关于 Node.js Express 中间件的资料请关注本站其它相关文章!

作者最新文章