9

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

假设我们有这个代码

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) 返回一个中间件,它在路由链中执行——我明白了。然而:

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

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

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

如果有人能指出基本想法会很酷:)

4

2 回答 2

9

1)req并且res来自 Express JS 的源头,即 Node.JShttp.createServer处理程序(这两个变量在实际命中 Express 处理程序之前都进行了一些修改)。此时 Express 保存了所有路由的数组,并对每条路由应用req,res和函数。函数知道我们目前在哪个中间件(由于一些范围技巧)并像这样调用它:带你到下一个处理程序。nextnextnext()

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

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

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

3)一点都不难:

安全.js

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

应用程序.js

app.get('/', require('./security'), ...);
于 2012-06-30T10:24:39.140 回答
1

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

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

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

于 2012-06-30T10:23:20.867 回答