Express JS处理程序中的res.send()是否自动调用next()?

时间:2018-12-04 18:04:06

标签: node.js express middleware

我知道一个人可以在ExpressJS处理程序中在next之后调用res.send,但是可以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

因此中间件似乎被调用了两次。

这是为什么?是否因为中间件也以某种方式被称为“直接”,而与路由无关?也就是说,即使在路由处理程序之后 ,它也总是被总是调用?但是我认为,如果是在路由处理程序之后,则要到达中间件,在其之前的路由处理程序必须调用ptrace,如此处的https://derickbailey.com/2016/05/09/in-what-order-does-my-express-js-middleware-execute/,其中说:“事实证明,添加顺序中间件很重要,并且由于在“获取”处理程序之后添加了第二个“使用”方法,因此永远不会调用它。“获取”处理程序在呈现页面时会短路中间件,从而阻止了任何其他中间件的处理。”

Express版本4.16.0,Node版本11.2.0

感谢您的澄清!

2 个答案:

答案 0 :(得分:2)

  

这是为什么?

这是因为浏览器发送了另外一个请求,以获取收藏夹;当您转到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的适当位置,因为如果到这一点,我们的应用程序路由都不会匹配。

答案 1 :(得分:0)

app.use() 中间件使您可以执行路由应遵循的一组操作。在实际对该路由执行指定操作之前,请考虑一下您的所有路由是否都会进行某些处理。

当我运行您的代码时,它打印在下面,并且Hello World在Mozilla(版本63.0.3(64位))和Chrome(版本71.0.3578.80)中都呈现了

  

在中间件的路由处理程序中..............

res.send() 现在来问您的问题,不需要在调用res.send()之后调用next()。因为一旦遇到它,它将立即发送响应。是的,您是正确的,中间件的顺序确实很重要。因此,当您在res.send()之后添加next()时,将执行以下操作:

  1. 首先,“ /”路由将在浏览器停止加载时返回Hello World
  2. 您的中间件将被调用两次,一次是由于next(),第二次是由于中间件本身。