2013-10-10 32 views
3

所以我見過TJ's guide to creating modular Express-apps,效果很好,但想知道更多關於它是如何工作的細節,但搜索沒有給出答案。在Express中如何安裝應用程序

總之我想知道:在Express中安裝應用程序時,應用程序的哪些部分是共享的,哪些部分不是?

一些例子,以澄清我的問題:

app.js:

app.use(express.bodyParser()); 

app.use(loginApi); //loginApi is an express app 

app.listen(3000); 

此示例適用。但是,如果我在app.use(express.bodyParser());之前放置app.use(loginApi),bodyArea解析器將不會在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的其他路線呢?他們會受到影響嗎?而如果我添加另一個模塊,會受到影響嗎?

回答

3

如果我將app.use(loginApi)放在app.use(express.bodyParser())之前; ,身體解析器將不會在loginApi子應用程序中可用。這是爲什麼?

這是因爲Express處理請求的方式。任何傳入請求都從中間件堆棧的頂部開始,從app.use()堆棧開始。

中間件只是具有功能簽名function(req, res, next)的功能,如果他們想要將請求轉交給後續功能,或者自己發送響應,則它們可以調用next()。您可以定義一堆這些功能的「中間件鏈」(許多是由快遞提供的,像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),並且此時請求將轉到您在外部應用中設置的路由功能。

所以答案是:A安裝的應用程序將共享中間件的功能,這是放置的行app.use(loginApi)

3

中間件依次運行(直到其中一箇中間件沒有調用next())。

如果use()荷蘭國際集團bodyParser之前use()你安裝的應用程序,整個子應用程序將bodyParser增加了它的屬性之前運行。

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從數據庫中定義,因此在後面的中間件中您將能夠引用用戶的屬性。但是,它也可以用於其他一些東西。

+0

之前順便說一句,你甚至不需要一個數組,你可以通過多種處理函數'應用。 get('whatever',fn1,fn2,fn3)' – Plato

+0

這不完全正確。您可以使用app.use()在相對目錄中「掛載」子應用程序。例如,'app.use('/ products',productService')將會爲所有匹配'/ products'的路徑使用'productService'中間件/應用程序,這些路徑不會被早期的路線所捕獲。 –

相關問題