我正在学习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参数引发的Error会发生什么?错误是否会破坏中间件链?
如果我想将限制机制打包到单独的文件/模块(如安全框架),那该怎么办呢?
如果有人能指出基本想法,那将会很酷:)
答案 0 :(得分:9)
1)req
和res
来自Express JS的源头,即Node.JS http.createServer
处理程序(在实际点击Express'处理程序之前,这两个变量都被修改了一下)。此时,Express保存所有路由的数组,并将req
,res
和next
函数应用于每个路由。 next
函数知道我们目前在哪个中间件(由于一些范围技巧)并且这样调用它:next()
将您带到下一个处理程序。
2)当引发错误(实际上不是引发,但传递给)时,next
函数会将您带到错误处理程序,您可以使用{{1}定义} error
的方法,例如(取自Express documentation):
app
提升app.error(function(err, req, res, next){
if (err instanceof NotFound) {
res.render('404.jade');
} else {
next(err);
}
});
打破一系列中间件并带您进入错误处理程序链(如您所见,您在错误处理程序中使用error
)。
3)一点都不困难:
<强> security.js 强>
next
<强> app.js 强>
module.exports = function(req, res, next) {
console.log('Security middleware!');
next();
}
答案 1 :(得分:1)
1)Express(实际上是Connect)的路由代码接受HTTP请求并开始将其传递给所有中间件函数,并使用随请求附带的req
和res
调用每个中间件函数,并添加next
,调用路由代码的一部分,将控制权传递给链中的下一个中间件函数。
2)没有引发错误(只有throw
语句实际上可能引发错误)。路由代码识别出中间件函数已返回Error
对象,并正确处理。
3)您只需将其放入导出andRestrict
的模块中(如果它是模块中唯一可外部使用的函数,则设置exports=andRestrict
然后使用{调用它} {1}});否则你设置require('mymodule')
并分两步调用它:exports.andRestrict=<body of your function>
早期,mymodule=require('mymodule')
稍后(例如,当它作为中间件传递时)。)