节点和节点中间件中的'req'和'res'参数是什么?

时间:2014-06-15 01:27:27

标签: javascript node.js express connect

我是Node和Express的新手以及与使用节点构建网络应用程序以及requestresponse参数一起使用的其他图层让我感到困惑。我的困惑在于,这两个参数通常存在于函数中,但通常不会声明其中的一个或两个。此外,大多数情况下会引入其他参数,例如'next'或其他参数。例如,我有一个API的以下路由器:

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?或者,如果我将它们命名为完全不同的东西?

请求和回复究竟发生了什么?对不起我的无知。我已经阅读了文档,但没有点击。

感谢。

3 个答案:

答案 0 :(得分: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);

因此,在第一种情况下,您可以使用req访问请求(例如,请求标头,完整网址,来电者IP地址或类似信息)。在第二种情况下,您可以通过拨打电话来访问它。在第三种情况下,您可以使用参数[0]。

按照惯例,人们会使用以下格式:myCallback(req, res)并知道Express会将请求对象作为第一个参数,并将响应作为第二个参数。响应对象实际上有一个方法end(),因此您可以结束请求。如果还有next()对象,则可以调用下一个中间件。

假设您的路线定义如下:

app.use('/api/users', checkAuthorizationHandler);
app.use('/api/users', makeSureTheIPisFromOurInternalNetwork);
app.use('/api/users', nowHandleTheResponse);

每个处理程序都获得第三个参数。如果你命名它,你通常在你的函数声明中称它为'next'参数。这意味着,顺序的下一个功能。

假设您的function checkAuthorizationHandler(req, res, next)将检查req.headers('auth')令牌,如果没问题,它将在函数体中调用next()

然后调用function makeSureTheIPisFromOurInternalNetwork(a, b, c)。它将检查a.ip是否为LAN IP地址并调用c();

最后,您的function nowHandleTheResponse()会找到所有用户,并使用用户的JSON对象进行回复:arguments[1].json([user1, user2, user3]);

所以,第一个param是表达给你的东西,它是请求,第二个是响应,第三个是下一个中间件函数。无论你怎么称呼他们,他们都在那里。

P.S。您还可以使用 four 参数声明中间件:

function(error, req, res, next);

Express会实际检查你的功能,如果它发现你有四个参数而不是两个或三个,它会给你链中早期运行的中间件抛出的任何错误。这意味着,如果你的checkAuthHandler说下一个(新的错误('未授权'));,你的下一个函数可能会检查该错误,如果它存在,则不给出结果。然而,检测错误的中间件通常会重新发送('某些错误消息');

如果我没有让你感到困惑,那就说,我得到的更多来自:)

答案 1 :(得分: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定义默认值?

希望这能澄清一些事情。

答案 2 :(得分: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()函数调用的重要性。