Каковы параметры ‘req’ и ‘res’ в node и node middleware?

#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() вызова функции.