2014-06-15 36 views
3

我是Node和Express的新手,其他一些與構建帶有節點的web應用程序一起工作的層,requestresponse參數讓我感到困惑。我的困惑在於,這兩個參數經常出現在一個函數中,但通常其中一個或兩個都沒有聲明。此外,大部分時間還會引入額外的參數,如'next'或其他內容。例如,我有一個API以下路由器:節點和節點中間件中的'req'和'res'參數是什麼?

router.route('/teams') 
    // create a team at POST http://localhost:8080/api/teams 
    .post(function(req, res) { 
     var team = new Team(); 
     team.name = req.body.name; 
     team.location = req.body.location; 

     // save the new team and check for errors 
     team.save(function(err) { 
      if (err) { 
       res.send(err); 
      }; 
      res.json({ message: 'Team created!' }); 
     }); 
    }) 
    // GET all the teams at GET http://localhost:8080/api/teams 
    .get(function(req, res) { 
     Team.find(function(err, teams){ 
      if (err) { 
       res.send(err); 
      }; 
      res.json(teams); 
     }); 
    }); 

兩個.post.get呼叫與reqres作爲參數的功能,但req從未使用過。那麼函數如何知道如果req或res如果沒有被定義和使用,或者沒有以完全不同的順序使用,該如何處理?或者如果我給他們命名完全不同的東西?

請求和響應到底發生了什麼?對不起,我的無知。我已閱讀文檔,但不是點擊。

謝謝。

+1

來到他們是從http://nodejs.org/的'request'和'response' API/http.html#http_event_request。 –

回答

6

當您使用expressApp.use('/some/route', myRouteHandler); Express將偵聽該路由的請求,當它被命中時,它將調用您提供的函數(回調)。它會給它三個參數:請求和響應,然後。 (實際上可能有四個,但讓我們保持簡單)

所以,你的回調可能是這樣定義的:

function myRouteHandler(a, b, c) { 
    // do stuff 
}; 

或像這樣:

function myRouteHandler(req, res, next) { 
    // stuff 
} 

或者乾脆:

function myRouteHandler() { 
    // stuff 
} 

無論你做什麼,沒關係。當應用程序啓動時,express會監聽請求。

當其中一個途徑(/some/route),明確表示不願繼續在其內部工作相匹配,請致電您所提供的功能,如:

myRouteHandler(requestObject, responseObject, nextMiddleware); 

所以在第一種情況下,你可以訪問請求(如,請求標題,完整的網址,來電IP地址或類似的)通過使用REQ。在你的第二種情況下,你可以通過調用一個來訪問它。在第三種情況下,您可以使用參數[0]。

按照慣例,人們將使用表格:myCallback(req, res),並且知道Express會將請求對象作爲第一個參數,並將響應作爲第二個參數。響應對象實際上有一個方法end(),所以你可以結束請求。如果還有next()對象,則可以調用下一個中間件。

說你有一個像這樣定義的路由:

這些處理器的
app.use('/api/users', checkAuthorizationHandler); 
app.use('/api/users', makeSureTheIPisFromOurInternalNetwork); 
app.use('/api/users', nowHandleTheResponse); 

每個獲得第三PARAM。如果你命名它,你通常會在你的函數聲明中調用它的'next'參數。這意味着,下一個功能按順序。

假設您的function checkAuthorizationHandler(req, res, next)將檢查req.headers('auth')令牌,如果沒有問題,它將在函數體中調用next()

然後調用function makeSureTheIPisFromOurInternalNetwork(a, b, c)。它會檢查a。IP是一個局域網的IP地址,並呼籲c();

最後你function nowHandleTheResponse()會發現所有用戶,與用戶的JSON對象作出迴應:arguments[1].json([user1, user2, user3]);

所以,第一個參數是表達給你的東西,它的要求,二是響應,三是下一個中間件功能。不管你怎麼稱呼他們,他們都在那裏。

P.S.你也可以用 PARAMS聲明中間件:

function(error, req, res, next); 

Express將實際檢查你的功能,如果發現你有四個PARAMS,而不是兩個或三個,它會給你通過中間件出現的任何錯誤在連鎖店的早期運行。意思是,如果你的checkAuthHandler接下來說(新的錯誤('未授權')),你的下一個函數可能會檢查錯誤,如果存在,不會給出結果。然而,通常會檢測錯誤的中間件只是res.end('一些錯誤消息');

如果我沒有讓你感到困惑的是,只是說,我有更多的這個地方從:)

+0

非常感謝您的好評!這清除了很多。如果你確實有更多...你會介意用兒童的術語解釋我在我的問題中發佈的'.post(function(req,res)'函數中發生了什麼?'.body'從何而來?何時發生?可用嗎?非常感謝。 – reknirt

+1

.post基本上是你發佈到網址的任何東西。我會用更多的例子更新答案:) – Zlatko

4

這是框架公約。第一個參數是request,第二個參數是response。如果您聲明中間件(.use),則第三個參數是鏈中的next中間件。

只要您知道訂單,您可以根據需要命名這些變量。你可能有這樣的:.post(function(a,b) {});,然後請求由變量a表示,並通過變量b響應。

如果由於某種原因您不需要請求,只有響應,您仍然必須有第一個參數,因爲響應由第二個參數表示。

在JavaScript中,例如沒有像Java那樣的過載方法(可能這裏是您從中弄混淆的地方)。一個函數由其名稱表示,而不是由多少個參數表示。這裏有一個簡單的例子:

function logToConsole(level, message) { 
    if (!message) { 
    message = level; 
    level = 'INFO'; 
    } 
    console.log('['+level+']', message); 
} 

logToConsole('My message'); // prints out: "[INFO] My message" 
logToConsole('WARN', 'My message'); // prints out: "[WARN] My message" 

你有沒有注意到,我們如何爲level定義了默認值的基礎上,message存在?

希望這可以澄清一些事情。

+0

順便說一句,你的'req'變量用在'.post'中以獲取發送的主體。 – gtramontina

1

Requestresponsenext被傳遞給所有中間件功能。 request對象包含有關HTTP request的信息,而response對象用於處理requestExpressjs documentation詳細介紹這些對象。 next()調用用於調度程序,中間件功能可能會或可能不會調用next(),具體取決於使用情況。 Next只需調用以下中間件。

下面是使用next()的例子:

function helloWorld(req,res,next){ 

    console.log('Hello, world!'); 
    next(); 
} 

// This function doesn't call next(), therefore it will 
// not call the subsequent middleware in the dispatcher 
function goodbyeWorld(req,res,next){ 
    console.log('Goodbye, world!'); 
} 

app.use(helloWorld); 
app.use(goodbyeWorld); 

輸出:

你好,世界!

再見,世界!

現在讓我們重新排序中間件

app.use(goodbyeWorld); 
app.use(helloWorld); 

輸出:

再見,世界!

helloWorld函數未被調用。注意中間件訂單和next()函數調用的重要性。

相關問題