Hello! 欢迎来到小浪资源网!



了解 Expressjs 中的中间件及其内部工作原理


了解 Expressjs 中的中间件及其内部工作原理

express.JS 中间件是特殊的函数,它们在处理 http 请求时扮演着关键角色。每个中间件函数都接收三个参数:请求对象 (req)、响应对象 (res) 和 next 函数。与普通的路由处理程序不同,中间件在主业务逻辑之前执行,从而控制应用程序的流程。

中间件的工作原理

当 HTTP 请求到达 Express.js 服务器时,它会依次经过一系列中间件函数。每个中间件都可以:

  • 修改请求对象 (req),例如添加数据或验证令牌。
  • 修改响应对象 (res),例如提前发送响应。
  • 调用 next() 函数,将控制权传递给下一个中间件或路由处理程序。

如果中间件不调用 next(),则请求-响应周期在此终止,后续逻辑(包括路由处理程序)将不会执行。

为什么要使用中间件?

中间件非常适合在处理请求之前添加可重用的逻辑,例如:

  • 身份验证: 验证用户是否已登录(例如,JWT 令牌验证)。
  • 授权: 确保用户拥有执行特定操作的权限(例如,管理员权限)。
  • 请求验证: 验证请求中是否包含所有必需的输入数据。
  • 日志记录和监控: 记录传入请求的详细信息,用于分析或调试。
  • 错误处理: 全局捕获错误,并发送有意义的错误响应。

定义和使用中间件

中间件函数的定义如下:

app.use((req, res, next) => {     // 在此处添加你的逻辑     next(); // 将控制权传递给下一个中间件或路由处理程序 });
  • req (请求): 包含传入 HTTP 请求的信息(例如,头信息、正文、参数)。
  • res (响应): 用于向客户端发送数据。
  • next(): 用于将控制权传递给下一个中间件函数。

中间件执行顺序

中间件的执行顺序至关重要!Express.js 按照定义的顺序依次执行中间件。如果中间件定义在路由之后,则不会影响该路由。因此,必须在 app.js 中的路由定义之前声明中间件。

示例:

// 中间件,用于检查用户是否具有管理员权限 app.use((req, res, next) => {     console.log("正在检查管理员角色...");      // 模拟之前在管道中附加的用户对象     if (req.user && req.user.role === "admin") {         console.log("访问已授权");         next(); // 转到下一个中间件或路由处理程序     } else {         console.log("访问被拒绝");         res.status(403).send("您无权访问此资源。");     } });  // 路由 app.get("/admin/dashboard", (req, res) => {     res.send("欢迎来到管理员控制面板!"); });  app.get("/public", (req, res) => {     res.send("这是一个公共页面。"); });

内部执行流程

流程如下:

  1. 传入请求: 请求到达服务器。
  2. 中间件执行:
    • 中间件检查 req.user.role。
    • 如果角色是 “admin”,则调用 next() 将控制权传递给下一个中间件或路由。
    • 如果不是,则中间件终止请求,并发送 403 Forbidden 响应。
  3. 路由处理程序: 如果调用了 next(),则执行相关的路由处理程序(例如 /admin/dashboard)。

流程示例:

  • 角色为 “admin” 的用户请求 /admin/dashboard:
    • 中间件记录 “访问已授权” 并调用 next()。
    • 路由处理程序发送 “欢迎来到管理员控制面板!”。
  • 角色为 “user” 的用户请求 /admin/dashboard:
    • 中间件记录 “访问被拒绝” 并发送 “您无权访问此资源。”。

关键要点

  • 中间件如同守门员,决定在主路由逻辑执行之前发生什么。
  • 使用 next() 确保流程继续到下一个中间件或路由。
  • 始终在路由之前定义关键中间件,以确保它们生效。
  • 如果不调用 next() 或发送响应,请求将挂起(超时)。

相关阅读