2011-08-08 52 views
3

這裏有三件在與ConnectJS對於一直習慣文檔的NodeJS使用的術語,但我不完全undertand:一些連接術語

1)視圖和控制器

2)的諧音和收藏品

3)中間件

回答

8

讓我們從頭開始。

0級:內置http模塊

在開始時,有節點。js的內置http.Server由Ryan Dahl編寫。你寫了一個function(req, res)和節點將調用函數中的每個新的連接被接受時間:

// Hello world HTTP server using http module: 
var http = require('http'); 
var app = http.createServer(function (req, res) { 
    res.writeHead(200, {'Content-Type': 'text/plain'}); 
    res.end('Hello, world.'); 
}); 
app.listen(8080, '127.0.0.1'); 

等級1:連接

Connect,由蒂姆·卡斯韋爾寫的,是一個簡單的是http.Server的子類可以更輕鬆地組織您的代碼。您不必編寫處理每個請求的單個回調,而是將一些中間件鏈接在一起。如果可能的話,每個中間件都是function(req, res, next),如果它沒有完成處理用戶請求,則會調用next(error)。中間件處理程序按其use的順序調用;最後你應該打電話給所有的app.use(connect.errorHandler())

一個重要的中間件是路由器,它允許您根據URL路徑的模式過濾一些中間件。 syntax for the route patterns基於ruby的Sinatra路線。當我使用過濾器/hello/:name時,req.params.name將被設置爲URL的匹配部分。

var connect = require('connect'); 
var app = connect.createServer(); 
app.use(connect.favicon()); 
app.use(connect.logger());, 
app.use(connect.router(function(app) { 
    app.get('/hello/:name', function(req, res, next) { 
    try { 
     if (Math.random() > 0.5) { 
     throw new Error('Random error!'); 
     } 
     res.writeHead(200, {'Content-Type': 'text/plain'}); 
     res.end('Hello, ' + req.params.name); 
    } catch (e) { 
     return next(e); 
    } 
    }); 
})); 
app.listen(8080, '127.0.0.1'); 

在Connect中,每個處理程序都是中間件!您可以使用您需要的任何功能,如bodyParser或cookieParser,而您自己的業務邏輯也是具有相同簽名function(req, res, next)的中間件功能。 connect homepage給出了內置中間件的列表。

等級2:Express.js

快速的HTTP服務器,由TJ Holowaychuk寫的,是依次連接的子類,迫使西納特拉風格比較。在連接,沒有魔法,你沒有要求,但在快遞,路由器和QS解析器(設置req.query)是自動use d。路由器語法被清理;你叫app.getapp.post等直接(和路由器被放置在第一次調用),而不是把他們一個函數內。

Express還包含了許多其他well-documented功能和輔助功能來擴展應用程序,REQ和資源。快遞

一個特點是res.render,這使得給定的模板文件(相對於app.set('views')或$ PWD /視圖)使用擴展隱含的模板引擎,並res.partial,它調用render集合中的每個元素(這只是任何類似的對象)。但我沒有使用這個可選功能;如果你不關心快遞的模板,你自己可以只用res.send數據。

+0

謝謝yonran!一個問題:什麼是「qs解析器」? – Randomblue

+0

'qs'是具有可以使用HTTP查詢字符串解析了'parse'方法建立在'qs'模塊(查詢字符串)Node.js的。 http://nodejs.org/docs/v0.5.3/api/querystring.html#querystring.parse –

+0

我敢肯定連接(如2013年4月)的船舶,無路由器。有一個稱爲urlrouter的中間件,其行爲與您描述的方式相同。 – sheldonh

3

下面是一些評論。如果您有更具體的問題,我們可以嘗試解決它們。

1)視圖和控制器

視圖只是意味着可用於呈現的響應時,它通常是HTML,但可以是純文本或者其它格式的模板。有許多不同的模板語法和系統。有些工作在NodeJS以及Web瀏覽器中。這就是所有觀點。

控制器是MVC設計模式中的「C」,它負責作爲視圖和模型之間的中介。它們基本上是處理一些基本事物的粘合劑,例如不屬於模型代碼的格式化選擇。

2)的諧音和收藏

(邊評論,這些都是真正的Express.js一部分,而不是連接,但他們是兄弟姐妹庫)

局部模板是代表的一小部分或片段的文檔模板文檔,而不是完整的HTML文檔。部分可以被其他模板包含,並且通常被多個包含模板重複使用。集合與他們攜手並進。例如,您可能有部分顯示「總統」對象,並且在該部分中,您可以爲照片添加標記,他擔任總統,政黨等日期。您可以隨時在整個網站中使用相同的部分想要顯示「總統」記錄/對象。如果您有幾個「總統」對象的集合,「集合」爲您提供了一種簡單的方法來說「讓總統在這個列表中成爲部分對象」。

3)中間件

的方式連接手柄響應HTTP請求是路由通過一系列稱爲中間件功能的請求。每個中間件功能都遵循基本的API (req, res, next)和一些行爲要求。每個中間件都可以執行一個特定的處理位,然後在完成後,調用next()來告訴連接移動到鏈中的下一個中間件功能。 Connect帶有一堆中間件模塊,您可以看到on github。中間件可以做任何想要的事情。例如,解析JSON請求主體,在文件系統中搜索匹配的靜態文件,檢查會話cookie,登錄到日誌文件等。這種設計使得重用代碼以及以新穎的組合方式組合獨立的中間件功能變得非常容易。一些中間件功能處理解析和處理請求,一些處理生成響應。通常,您可以找到現有的中間件功能,它們執行大量的請求處理(解析,日誌記錄,解碼,轉換等),並且提供自己的中間件以實際呈現響應,這通常也是鏈中的最後一箇中間件。

+0

感謝彼得。你說明使用'next()'與yonran(見下文)有所不同,即如果中間件未能完成其任務,將調用'next(error)'。 – Randomblue

+0

@yonran在這裏可能是正確的。在快遞指南中,如果發生未經授權的請求,他會調用「下一個(錯誤)」,因此可能會更好。我會編輯我的答案。 –