Вызывает ли res.send () в обработчике Express JS автоматический вызов next ()? - PullRequest
0 голосов
/ 04 декабря 2018

Я понимаю, что один может вызвать next после res.send в обработчике ExpressJS, но разве res.send 'автоматически' вызывает next в любом случае?

У меня есть следующий код

const express = require('express');

var app = express();

app.get('/', (req, res, next) => {
  console.log('in route handler')
  res.send('Hello World')
});

app.use((req,res, next) => {
  console.log('in middleware')
  console.log('...........')
})

app.listen(process.env.PORT || 8080)

Мой журнал консоли

in route handler
in middleware
...........

Если я действительно вызываю next явно после res.send Я получаю

in route handler
in middleware
...........
in middleware
...........

и, таким образом, кажется, что промежуточное ПО вызывается дважды.

Почему это так?Это потому, что промежуточное программное обеспечение также называется «напрямую» каким-то образом, независимо от маршрута?То есть он просто всегда вызывается, даже если он после обработчиков маршрута?Но я подумал, что если после обработчиков маршрута для достижения промежуточного программного обеспечения предшествующий ему обработчик маршрута должен вызвать next, как здесь https://derickbailey.com/2016/05/09/in-what-order-does-my-express-js-middleware-execute/,, где написано: «Получается порядок добавления промежуточного программного обеспечения.Это важно. А поскольку второй метод «use» добавляется после обработчика «get», он никогда не вызывается. Обработчик «get» закорачивает промежуточное программное обеспечение при рендеринге страницы, предотвращая дальнейшую обработку промежуточного программного обеспечения ».

Экспресс версия 4.16.0, версия узла 11.2.0

Спасибо за любые разъяснения!

Ответы [ 2 ]

0 голосов
/ 10 декабря 2018

Почему это так?

Это связано с тем, что браузеры отправляют дополнительный запрос для получения favicon ;Когда вы переходите на localhost:8080, chrome (или firefox) отправляет запрос get на /, следовательно, ваш сервер соответствует этому маршруту и ​​регистрирует:

in route handler

Сразу после этого он отправляет вторую getзапрос к /favicon.ico, но ваш сервер не соответствует ни одному маршруту.он продолжает свой путь к промежуточному программному обеспечению, смонтированному после маршрутизации, и записывает в журнал:

in middleware
...........

Конечно, вызвав next(), вы явно вызвали свое промежуточное программное обеспечение после двух вышеуказанных запросов и так:

in route handler
in middleware
...........
in middleware
...........

Но я подумал, что если это было после обработчиков маршрутов, то для достижения промежуточного программного обеспечения предшествующий ему обработчик маршрута должен вызвать следующий

Конечно, вы правы.Добавьте serve-favicon промежуточное программное обеспечение в свое приложение, и ваше пользовательское промежуточное программное обеспечение никогда не будет вызываться без явного вызова next(), если ни один из маршрутов не будет сопоставлен:

const express = require('express');
var favicon = require('serve-favicon')
var path = require('path')

var app = express()
app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')))

app.get('/', (req, res, next) => {
  console.log('in route handler')
  res.send('Hello World')
});

app.use((req,res, next) => {
  console.log('in middleware')
  console.log('...........')
})

app.listen(process.env.PORT || 8080)

Кстати, это промежуточное ПО, смонтированное после всех маршрутов,подходящее место для обработки 404-х, потому что если мы доберемся до этой точки, ни один из маршрутов наших приложений не будет найден.

0 голосов
/ 09 декабря 2018

app.use () Промежуточное ПО позволяет вам иметь набор действий, которым должны следовать ваши маршруты.Представьте себе, как будто все ваши маршруты выполнят некоторую обработку перед тем, как на самом деле выполнить назначенное действие для этого маршрута.

Когда я запустил ваш код, он был напечатан ниже, и Hello World отображался в обоих Mozilla (Версия 63.0.3 (64-битная))) и Chrome (версия 71.0.3578.80)

в обработчике маршрута в промежуточном программном обеспечении ...........

res.send () Теперь перейдем к вашему вопросу, нет необходимости вызывать next () после вызова res.send ().Потому что, как только он обнаружен, он немедленно отправит ответ.И да, вы правы, порядок промежуточного программного обеспечения имеет значение.Поэтому, когда вы добавили next () после res.send (), были выполнены следующие действия:

  1. Сначала маршрут '/' вернет Hello World, когда браузер прекратит загрузку
  2. Ваше промежуточное ПОбудет вызываться дважды, один раз из-за next () и второй раз из-за самого промежуточного программного обеспечения.
...