#javascript #node.js #express #connect
#javascript #node.js #экспресс #Контакты
Вопрос:
Я новичок в Node и Express, а другие уровни, связанные с созданием веб-приложений с request
помощью node и response
параметров and, действительно сбивают меня с толку. Мое замешательство заключается в том, что эти два параметра часто присутствуют в функции, но часто один или оба из них не объявлены. Кроме того, большую часть времени будет добавляться дополнительный параметр, например '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
вызывают функцию с req
res
параметрами и как, но req
никогда не используются. Итак, как функция узнает, что делать с req или res, если они не определены и не используются или не используются в совершенно разных порядках? Или если я назвал их как-то совершенно по-другому?
Что именно происходит с запросами и ответами? Извините за мое невежество. Я прочитал документацию, но она не щелкает.
Спасибо.
Комментарии:
1. Они
request
иresponse
из nodejs.org/api/http.html#http_event_request .
Ответ №1:
Когда вы используете expressApp.use('/some/route', myRouteHandler);
Express, он будет прослушивать запросы для этого маршрута, и когда он попадет, он вызовет предоставленную вами функцию (обратный вызов). Это даст ему три параметра: запрос и ответ, и следующий. (На самом деле их может быть четыре, но давайте не будем усложнять.)
Итак, ваш обратный вызов может быть определен следующим образом:
function myRouteHandler(a, b, c) {
// do stuff
};
или вот так:
function myRouteHandler(req, res, next) {
// stuff
}
или просто:
function myRouteHandler() {
// stuff
}
Что бы вы ни делали, это не имеет значения. При запуске приложения express прослушивает запросы.
Когда один из них соответствует route ( /some/route
) , express в своей внутренней работе вызовет предоставленную вами функцию, например:
myRouteHandler(requestObject, responseObject, nextMiddleware);
Итак, в первом случае вы можете получить доступ к запросу (например, заголовки запроса, полный URL-адрес, IP-адрес вызывающего абонента или аналогичный) с помощью req. Во втором случае вы получите к нему доступ, вызвав a . В третьем случае вы можете использовать аргументы [0] .
По соглашению люди будут использовать form: 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 является IP-адресом локальной сети, и вызовет c();
Наконец, вы function nowHandleTheResponse()
найдете всех пользователей и ответите JSON-объектом пользователей: arguments[1].json([user1, user2, user3]);
Итак, первый параметр — это то, что дает вам express, это запрос, второй — ответ, третий — следующая функция промежуточного программного обеспечения в очереди. Независимо от того, как вы их называете, они есть.
PS Вы также можете объявить свое промежуточное программное обеспечение с четырьмя параметрами:
function(error, req, res, next);
Express фактически проверит вашу функцию, и если он обнаружит, что у вас четыре параметра, а не два или три, он выдаст вам любые ошибки, вызванные промежуточным программным обеспечением, которое выполнялось ранее в цепочке. Это означает, что если ваш checkAuthHandler сообщает next (новая ошибка (‘Не авторизован’)); , ваша следующая функция может проверить наличие этой ошибки и, если она присутствует, не даст результатов. Однако часто промежуточное программное обеспечение, которое обнаруживает ошибки, просто res.end (‘некоторое сообщение об ошибке’);
Если я недостаточно вас запутал, просто скажите, у меня есть еще кое-что, откуда это взялось 🙂
Комментарии:
1. большое спасибо за отличный ответ! Это многое проясняет. Если у вас есть больше… не могли бы вы объяснить в детских терминах, что происходит в
.post(function(req, res)
функции, которую я опубликовал в своем вопросе? Откуда.body
берется и когда оно доступно? Большое спасибо.2. .post — это в основном все, что вы ОТПРАВЛЯЕТЕ по URL. Я обновлю ответ дополнительными примерами 🙂
Ответ №2:
Это рамочное соглашение. Первый аргумент — это the request
, второй — the 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
?
Надеюсь, это немного прояснит ситуацию.
Комментарии:
1. Кстати, ваша
req
переменная используется в вашем.post
, чтобы получить отправленное тело.
Ответ №3:
Request
response
и next
передаются всем функциям промежуточного программного обеспечения. request
Объект содержит информацию о HTTP request
, и response
объект используется для обработки request
. Документация Expressjs подробно описывает эти объекты. 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()
вызова функции.