express.js 中的中间件功能范围

Posted

技术标签:

【中文标题】express.js 中的中间件功能范围【英文标题】:Scope of middleware functions in express.js 【发布时间】:2012-07-01 14:45:23 【问题描述】:

我正在学习 express.js / node.js 并且对 javascript 原型模型有很好但不是很好的理解。因此,对于中间件在 express.js 的路由机制中的堆叠方式,我有点困惑。

假设我们有这个code

function andRestrictTo(role) 
    return function(req, res, next) 
       req.authenticatedUser.role == role
           ? next() : next(new Error('Unauthorized'));
   


app.del('/user/:id', loadUser, andRestrictTo('admin'), function(req, res)
    res.send('Deleted user ' + req.user.name);
);

由于 andRestrictTo(role) 返回一个中间件,它在路由链中执行 - 我明白了。然而:

    返回函数中req、res、next参数从何而来?我猜“链”以某种方式对其进行排队并分配参数,但这对于更深入的理解来说有点太模糊了......

    作为 next 参数引发的错误发生了什么?错误是否会破坏中间件链?

    如果我想将限制机制打包到单独的文件/模块中(如安全框架),该怎么做?

如果有人能指出基本想法,那就太酷了:)

【问题讨论】:

【参考方案1】:

1) reqres 来自 Express JS 的源头,即 Node.JS http.createServer 处理程序(这两个变量在实际使用 Express 处理程序之前都进行了一些修改)。此时,Express 持有所有路由的数组,并将reqresnext 函数应用于每条路由。 next 函数知道我们目前处于哪个中间件(由于一些作用域技巧)并像这样调用它:next() 将您带到下一个处理程序。

2) 当错误被引发(实际上不是引发,而是传递给)时,next 函数会将您带到错误处理程序,您可以使用@ 的error 方法定义错误处理程序例如987654332@(取自Express documentation):

app.error(function(err, req, res, next)
    if (err instanceof NotFound) 
        res.render('404.jade');
     else 
        next(err);
    
);

引发error 会破坏中间件链并将您带到错误处理程序链(如您所见,您也在错误处理程序中使用next)。

3) 一点都不难:

security.js

module.exports = function(req, res, next) 
    console.log('Security middleware!');
    next();

app.js

app.get('/', require('./security'), ...);

【讨论】:

【参考方案2】:

1) Express 的(实际上是 Connect 的)路由代码接受一个 HTTP 请求并开始将其传递给所有中间件函数,并使用请求随附的 reqres 调用它们中的每一个,并添加一个next 调用路由代码的一部分,将控制权传递给链中的下一个中间件函数。

2) 没有引发错误(只有throw 语句实际上可以引发错误)。路由代码识别出一个中间件函数返回了一个Error 对象,并进行了适当的处理。

3) 您只需将其放入导出andRestrict 的模块中(如果它是模块中唯一可在外部使用的函数,您将设置exports=andRestrict,然后使用require('mymodule') 调用它);否则你会设置 exports.andRestrict=<body of your function> 并分两步调用它:mymodule=require('mymodule') 早期,mymodule.andRestrict 稍后(例如,当它作为中间件传递时))。

【讨论】:

以上是关于express.js 中的中间件功能范围的主要内容,如果未能解决你的问题,请参考以下文章

Express.js 中间件为上面定义的路由执行

Express JS 中的中间件是啥

如何将参数传递给 Express JS 中的中间件函数?

在express.js中间件请求中获取“#”之后的url

Express/Koa/Hapi

无法使用 Express.js 从请求中获取 POST 正文