從技術上講,您在 Sails 應用程式中撰寫的大部分程式碼都是中介軟體,它運行於傳入的請求和傳出的回應之間——也就是在請求/回應堆疊的「中間」。在 MVC 框架中,「中介軟體」一詞通常更具體地指在您的路由處理程式碼(即您的控制器動作)之前或之後運行的程式碼,使其有可能將相同的程式碼片段應用於多個路由或動作。Sails 對中介軟體設計模式有強大的支援。根據您的需求,您可以選擇實作
routes
功能的 Hook (Hooks)——在一個或多個路由處理器之前套用程式碼Sails 完全相容於 Express / Connect 中介軟體,這些中介軟體是接受 req
、res
和 next
作為參數的函式。每個應用程式都利用可配置的中介軟體堆疊來處理 HTTP 請求。每次應用程式收到 HTTP 請求時,其配置的 HTTP 中介軟體堆疊都會依序運行。
請注意,此 HTTP 中介軟體堆疊僅用於「真實」的 HTTP 請求;**虛擬請求**(例如,來自即時 Socket.io 連線的請求)會被忽略。
預設情況下,Sails 使用一些不同的中介軟體函式來處理低階 HTTP 相關任務。這些任務包括解讀 Cookie、解析 HTTP 請求正文、提供資源,甚至附加您應用程式的路由。您可以這裡閱讀更多關於預設中介軟體堆疊的資訊。
由於中介軟體堆疊帶有合理的預設值,許多 Sails 應用程式根本不需要修改此配置。但是,在您需要更多彈性的情況下,Sails 可以輕鬆地新增、重新排序、覆寫和停用您應用程式 HTTP 中介軟體堆疊中的函式。
若要配置新的自訂 HTTP 中介軟體函式,請將中介軟體函式新增為 middleware
中的新鍵(例如「foobar」),然後在 middleware.order
陣列中新增其鍵的名稱(「foobar」),無論您希望它在middleware 鏈中哪個位置運行。
除了「order」保留用於配置中介軟體堆疊的順序外,分配給 sails.config.middleware
鍵的任何值都應該是一個接受三個參數的函式:req
、res
和 next
。此函式的工作方式幾乎與政策 (policy)完全相同,唯一可見的區別在於它的執行時間。
如果您需要為自訂中介軟體函式運行一些一次性的設定程式碼,您需要在傳入它之前執行此操作。建議的方法是使用自調用(即「立即調用」)包裝函式。在下面的範例中,請注意不是將值直接設定為「req, res, next」函式,而是使用自調用函式來「包裝」一些初始設定程式碼。然後,該自調用包裝函式會傳回最終的中介軟體 (req,res,next) 函式,因此它會以與直接傳入相同的方式設定在鍵上。
以下範例示範如何設定三個不同的自訂 HTTP 中介軟體函式
// config/http.js
module.exports.http = {
middleware: {
order: [
'cookieParser',
'session',
'passportInit', // <==== If you're using "passport", you'll want to have its two
'passportSession', // <==== middleware functions run after "session".
'bodyParser',
'compress',
'foobar', // <==== We can put other, custom HTTP middleware like this wherever we want.
'poweredBy',
'router',
'www',
'favicon',
],
// An example of a custom HTTP middleware function:
foobar: (function (){
console.log('Initializing `foobar` (HTTP middleware)...');
return function (req,res,next) {
console.log('Received HTTP request: '+req.method+' '+req.path);
return next();
};
})(),
// An example of a couple of 3rd-party HTTP middleware functions:
// (notice that this time we're using an existing middleware library from npm)
passportInit : (function (){
var passport = require('passport');
var reqResNextFn = passport.initialize();
return reqResNextFn;
})(),
passportSession : (function (){
var passport = require('passport');
var reqResNextFn = passport.session();
return reqResNextFn;
})()
},
}
您也可以使用上述策略來覆寫內建中介軟體,例如 body parser(請參閱自訂 body parser)。
雖然不建議這樣做,但您甚至可以完全停用內建的 HTTP 中介軟體函式——只需將其從
middleware.order
陣列中移除即可。這允許完全的彈性,但應謹慎使用。如果您選擇停用某個內建中介軟體,請確保您完全理解其後果。停用內建 HTTP 中介軟體可能會大幅改變您應用程式的運作方式。
Sails 應用程式真正的好處之一是它們可以利用現有豐富的 Express/Connect 中介軟體,但是當人們實際嘗試這樣做時,通常會出現一個問題
「我應該在哪裡
app.use()
這個東西?」.
在大多數情況下,答案是在sails.config.http.middleware
中將 Express 中介軟體安裝為自訂 HTTP 中介軟體。這將為所有發送到您的 Sails 應用程式的 HTTP 請求觸發它,並允許您配置它相對於其他 HTTP 中介軟體運行的順序。
您不應覆寫或移除
router
HTTP 中介軟體。它是 Sails 的內建元件;沒有它,您應用程式的顯式路由和藍圖路由將無法運作。
為了使 Express 中介軟體僅適用於特定動作,您也可以將 Express 中介軟體包含為政策 (policy)——只需確保您確實希望它同時為 HTTP 和虛擬 Socket 請求運行。
若要執行此操作,請編輯config/policies.js
,以在實際的包裝政策 (wrapper policy)(通常是個好主意)中要求和設定中介軟體,或直接在您的 policies.js 檔案中要求它。以下範例使用後者策略以求簡潔
var auth = require('http-auth');
var basic = auth.basic({
realm: 'admin area'
}, function (username, password, onwards) {
return onwards(username === 'Tina' && password === 'Bullock');
});
//...
module.exports.policies = {
'*': [true],
// Prevent end users from doing CRUD operations on products reserved for admins
// (uses HTTP basic auth)
'product/*': [auth.connect(basic)],
// Everyone can view product pages
'product/show': [true]
}