[英]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应用程序以及request
和response
参数一起让我感到困惑。 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
都使用req
和res
作为参数调用函数,但从不使用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. Request
, response
和next
传递给所有中间件函数。 The request
object contains information about the HTTP request
, and the response
object is used to handle the request
. request
对象包含有关HTTP request
, response
对象用于处理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.