简体   繁体   English

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

[英]What are the 'req' and 'res' parameters in node and node middleware?

I'm new to Node and Express and the other layers that go along with building web apps with node and the request and response parameters are really confusing me. 我是Node和Express的新手,其他层与建立带节点的Web应用程序以及requestresponse参数一起让我感到困惑。 My confusion lies in the fact that those two parameters are often present in a function but oftentimes one or both of them isn't declared. 我的困惑在于这两个参数通常存在于函数中,但通常不会声明其中的一个或两个。 Also, much of the time an additional parameter will be thrown in, like 'next' or something else. 此外,大多数情况下会引入其他参数,例如'next'或其他内容。 For example, I have the following router for an API: 例如,我有一个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);
        });
    });

Both .post and .get call a function with req and res as parameters, but req is never used. .post.get都使用reqres作为参数调用函数,但从不使用req So how does the function know what to do with req or res if they're not defined and used or not used in completely different orders? 那么,如果没有定义和使用或者没有在完全不同的订单中使用,该函数如何知道如何处理req或res? Or if I named them something completely different? 或者如果我给他们命名完全不同的东西?

What exactly is happening with requests and responses? 请求和响应究竟发生了什么? Sorry for my ignorance. 对不起我的无知。 I've read the documentation but it's not clicking. 我已经阅读了文档,但没有点击。

Thanks. 谢谢。

When you use expressApp.use('/some/route', myRouteHandler); 当你使用expressApp.use('/some/route', myRouteHandler); Express will listen for requests for that route, and when it's hit, it will call the function you provided (callback). Express将侦听该路由的请求,当它被命中时,它将调用您提供的功能(回调)。 It will give it three parameters: request and response, and next. 它将为它提供三个参数:请求和响应,以及下一个。 (Actually could be four, but lets keep things simple.) (实际上可能是四个,但是让事情变得简单。)

So, your callback might be defined like this: 所以,你的回调可能是这样定义的:

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

or like this: 或者像这样:

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

or simply: 或者干脆:

function myRouteHandler() {
    // stuff
}

Whatever you do, doesn't matter. 无论你做什么,都无关紧要。 When the app is started, express listens for requests. 应用程序启动时,express会侦听请求。

When one of them matches the route ( /some/route ), express will, in its internal workings, call the function you provided, like this: 当其中一个匹配路由( /some/route )时,express将在其内部工作中调用您提供的函数,如下所示:

myRouteHandler(requestObject, responseObject, nextMiddleware);

So in the first case, you can access the request (like, request headers, full url, caller IP address or similar) by using req. 因此,在第一种情况下,您可以使用req访问请求(例如,请求标头,完整网址,来电者IP地址或类似信息)。 In your second case, you'll access it by calling a. 在第二种情况下,您可以通过拨打电话来访问它。 In the third case, you can use arguments[0]. 在第三种情况下,您可以使用参数[0]。

By convention, people will use the form: myCallback(req, res) and know that Express will put the request object as the first param, and response as the second. 按照惯例,人们将使用以下形式: myCallback(req, res)并知道Express将把请求对象作为第一个参数,并将响应作为第二个参数。 The response object actually has a method end(), so you can end the request. 响应对象实际上有一个方法end(),因此您可以结束请求。 If there is also a next() object, you can call the next middleware. 如果还有next()对象,则可以调用下一个中间件。

Say you have a route defined like this: 假设你有一个像这样定义的路线:

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

Each of those handlers gets a third param. 每个处理程序都获得第三个参数。 If you name it, you'd usually in your function declaration call it 'next' parameter. 如果你命名它,你通常在你的函数声明中称它为'next'参数。 It means, the next function in order. 这意味着,下一个功能是有序的。

Say your function checkAuthorizationHandler(req, res, next) will check for req.headers('auth') token and if it's ok, it will in the function body, call next() . 假设您的function checkAuthorizationHandler(req, res, next)将检查req.headers('auth')令牌,如果没有问题,它将在函数体中调用next()

Then the function makeSureTheIPisFromOurInternalNetwork(a, b, c) is called. 然后function makeSureTheIPisFromOurInternalNetwork(a, b, c) It will check that the a.ip is a LAN ip address and call c(); 它将检查a.ip是否为LAN IP地址并调用c();

Finally your function nowHandleTheResponse() will find all users, and respond with a JSON object of the users: arguments[1].json([user1, user2, user3]); 最后你的function nowHandleTheResponse()将找到所有用户,并使用用户的JSON对象进行响应: arguments[1].json([user1, user2, user3]);

So, first param is something that express gives you, it's the request, second is response, third is a next middleware function in line. 所以,第一个param是表达给你的东西,它是请求,第二个是响应,第三个是下一个中间件函数。 No matter what you call them, they are there. 无论你怎么称呼他们,他们都在那里。

PS You can also declare your middleware with four params: PS你也可以用四个参数声明你的中间件:

function(error, req, res, next);

Express will actually check your function and if it finds that you have four params and not two or three, it will give you any errors thrown by the middleware that ran earlier in the chain. Express实际上会检查你的功能,如果它发现你有四个params而不是两个或三个,它会给你在链中早期运行的中间件抛出的任何错误。 Meaning, if your checkAuthHandler says next(new Error('Not authorized'));, your next function might check for that error, and if it's present, not give results. 这意味着,如果你的checkAuthHandler说下一个(新的错误('未授权'));,你的下一个函数可能会检查该错误,如果它存在,则不给出结果。 Often however will the middleware which detects errors just res.end('some error message'); 然而,检测错误的中间件通常会重新发送('某些错误消息');

If I haven't confused you enough, just say, I've got more where this came from :) 如果我没有把你弄糊涂,那就说,我有更多来自这里:)

It is the framework convention. 这是框架公约。 The first argument is the request , the second is the response . 第一个参数是request ,第二个参数是response If you're declaring a middleware ( .use ), the third argument is the next middleware in the chain. 如果您要声明中间件( .use ),则第三个参数是链中的next中间件。

You can name these variables however you want, as long as you know the order. 只要您知道订单,就可以根据需要为这些变量命名。 You could have something like: .post(function(a,b) {}); 你可以有类似的东西: .post(function(a,b) {}); and then the request is represented by variable a , and response by variable b . 然后请求由变量a表示,响应由变量b

If, for whatever reason, you don't need the request, only the response, you still have to have a first argument, as the response is represented by the second argument. 如果由于某种原因,您不需要请求,只需要响应,您仍然必须有第一个参数,因为响应由第二个参数表示。

In javascript, there's no method overload like in Java, for example (maybe here's where you getting the confusion from). 在javascript中,没有像Java中那样的方法重载(例如,这可能是你从中获得混淆的地方)。 A function is represented by its name, not how many arguments it takes. 函数由其名称表示,而不是由多少个参数表示。 Here's a simple example: 这是一个简单的例子:

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"

Did you notice how we defined a default value for level , based on the existence of message ? 您是否注意到我们如何根据message的存在定义level的默认值?

Hope this clarifies things a bit. 希望这能澄清一些事情。

Request , response and next are passed to all middleware functions. Requestresponsenext传递给所有中间件函数。 The request object contains information about the HTTP request , and the response object is used to handle the request . request对象包含有关HTTP requestresponse对象用于处理request The Expressjs documentation details these objects. Expressjs文档详细介绍了这些对象。 The next() call is used in something called the dispatcher, a middleware function may or may not call next() depending on usage. next()调用用于调度程序,中间件函数可能会或可能不会调用next()具体取决于用法。 Next simply calls the following middleware. Next只需调用以下中间件。

Here is an example of using 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);

Output: 输出:

Hello, world! 你好,世界!

Goodbye, world! 世界再见!

Now let's reorder the middleware 现在让我们重新排序中间件

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

Output: 输出:

Goodbye, world! 世界再见!

The helloWorld function is not called. 不调用helloWorld函数。 Notice the importance of middleware order and the next() function call. 注意中间件订单和next()函数调用的重要性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM