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

wqlqzqxt  于 2023-05-28  发布在  Node.js
关注(0)|答案(3)|浏览(159)

我是Node和Express的新手,使用node和requestresponse参数构建Web应用程序的其他层真的让我感到困惑。我的困惑在于,这两个参数经常出现在函数中,但通常它们中的一个或两个都没有声明。而且,很多时候会抛出一个额外的参数,比如'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没有被定义和使用,或者没有以完全不同的顺序使用,函数如何知道如何处理它们呢?或者我给它们起个完全不同的名字?
请求和响应到底发生了什么?抱歉我的无知。我看了文档,但没有点击。
谢谢。

daupos2t

daupos2t1#

当您使用expressApp.use('/some/route', myRouteHandler); Express时,它将侦听该路由的请求,当它被命中时,它将调用您提供的函数(回调)。它会给予它三个参数:请求和响应,然后是下一个。(实际上可能是四个,但让我们保持简单。
所以,你的callback可以这样定义:

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

或者像这样:

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

或者简单地说:

function myRouteHandler() {
    // stuff
}

不管你做什么都没关系。当应用程序启动时,express会侦听请求。
当其中一个匹配路由(/some/route)时,express将在其内部工作中调用您提供的函数,如下所示:

myRouteHandler(requestObject, responseObject, nextMiddleware);

因此,在第一种情况下,您可以通过使用req访问请求(如请求头,完整的url,呼叫者IP地址或类似内容)。在第二种情况下,您将通过调用。在第三种情况下,您可以使用arguments[0]。
按照惯例,人们会使用以下形式:myCallback(req, res)并知道Express将请求对象作为第一个参数,响应作为第二个参数。response对象实际上有一个end()方法,因此您可以结束请求。如果还有一个next()对象,则可以调用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')token,如果没有问题,它将在函数体中调用next()
然后调用function makeSureTheIPisFromOurInternalNetwork(a, b, c)。它将检查a.ip是否是LAN IP地址并调用c();
最后,function nowHandleTheResponse()将找到所有用户,并使用用户的JSON对象进行响应:arguments[1].json([user1, user2, user3]);
所以,第一个参数是express给你的,它是请求,第二个是响应,第三个是下一个中间件函数。不管你叫他们什么,他们就在那里。
P.S.你也可以用 * 四个 * 参数声明你的中间件:

function(error, req, res, next);

Express实际上会检查你的函数,如果它发现你有四个参数,而不是两个或三个,它会给予你任何由链中早期运行的中间件抛出的错误。意思是,如果你的checkAuthHandler说next(new Error('Not authorized'));,您的下一个函数可能会检查该错误,如果它存在,则不给予结果。然而,通常检测错误的中间件只是res.end('some error message');
如果我还没有把你弄糊涂,就说,我还有更多的东西:)

brccelvz

brccelvz2#

这是一个框架公约。第一个参数是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"

您是否注意到我们是如何根据message的存在为level定义默认值的?
希望这能澄清一些事情。

mzsu5hc0

mzsu5hc03#

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);

输出:
Hello,world!
再见了,世界!
现在让我们重新排序中间件

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

输出:
再见了,世界!
不调用helloWorld函数。请注意中间件顺序和next()函数调用的重要性。

相关问题