2014-06-15 33 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()函数调用的重要性。

相关问题