所以我看过TJ's guide to creating modular Express-apps,效果很好,但想知道更多关于它如何工作的详细信息,但搜索没有给我任何答案。
简而言之,我想知道:在Express中安装应用时,应用的哪些部分是共享的,哪些部分不是?
澄清我的问题的一些例子:
app.js:
app.use(express.bodyParser());
app.use(loginApi); //loginApi is an express app
app.listen(3000);
此示例有效。但是,如果我将app.use(loginApi)
放在app.use(express.bodyParser());
之前,则身份解析器将无法在loginApi子应用程序中使用。那是为什么?
另一个例子:
submodule.js
var app = module.exports = require('express')();
app.all('*', function(req, res, next){
console.log('nifty middleware');
next();
});
app.js
app.get('/funtimes', fn);
app.use(submodule);
app.listen(3000);
现在在这个例子中,如果我理解正确,/funtimes
路由不会受到所有路由的子模块中间件的影响。但app.js的其他路线怎么样?他们会受到影响吗?如果我添加另一个模块,它会受到影响吗?
答案 0 :(得分:3)
中间件按顺序运行(直到其中一个中间件不调用next()
)。
如果您在use()
use()
bodyParser
之前bodyParser
已安装的应用,则整个子应用将在{{1}}添加其属性之前运行。
答案 1 :(得分:3)
如果我在app.use(express.bodyParser())之前放置app.use(loginApi); ,身体解析器将无法在loginApi子应用程序中使用。那是为什么?
这是因为Express处理请求的方式。任何传入请求都从中间件堆栈的顶部开始,从app.use()
堆栈开始。
中间件只是具有函数签名function(req, res, next)
的函数,如果他们想要将请求移交给后续函数,则调用next()
,或者自己发送响应。您定义了一系列这些函数的“中间件链”(许多函数由express表示,如express.logger()
和express.compress()
。)
所以在以下场景中:
app.use(express.bodyParser());
var loginApi = require('./api/index.js')
app.use(loginApi);
app.use(app.router);
然后传入的请求将首先点击app.use(express.bodyParser())
,解析req.body
。然后该函数调用其内部next()
,将其传递给中间件链(app.use(loginApi)
)中的下一个函数。 loginApi应用程序有自己的中间件链,但请求已经从外部应用程序设置req.body
。如果loginApi没有发送响应,请求将继续app.use(app.router)
,此时请求将转到您在外部应用程序中设置的路由功能。
所以答案是:已安装的应用程序将共享中间件功能,这些功能位于行app.use(loginApi)
答案 2 :(得分:2)
您要问的是中间件。这困惑了我一段时间。中间件是为了接收请求并回送响应而运行的功能。 app.use()将函数作为唯一参数。该函数以一致的方式处理请求。
app.use与app.all(“*”)非常相似。
订单很重要。例如,您可能希望在提供响应之前运行验证程序。
我最近学到的一件事是你可以将一系列中间件函数传递给路由。例如
app.get("/whatever",[
function(req,res,next}{
...validation...
next();
},
function(req,res) {
...actions....
res.send(200);
}
]);
下一个回调告诉express在中间件中运行下一个函数。中间件还可以修改请求对象。这在身份验证中经常使用。例如,您将看到从数据库中定义req.user,因此在以后的中间件中,您将能够引用用户的属性。但是,它也可以用于其他许多东西。