NodeJS中间件调用顺序



当我请求localhost:3000时,为什么res.send("main page 2")不覆盖res.send("main page 1")
在NodeJS中执行此代码时,只有console.log("midddleware")app.use方法调用,而不是res.send。我想知道为什么它会那样工作。

const express = require('express')
const app = express()
app.get('/', function(req, res){
res.send("main page 1")
})
app.use("/", function(req, res) {
res.send("main page 2")
console.log("midddleware")
})
app.listen(3000)

您很可能被浏览器发送到服务器的第二个请求(favicon.ico(欺骗了。

更详细地检查你的代码,下面是它的作用:

const express = require('express')
const app = express()
app.get('/', function(req, res){
res.send("main page 1")
})
app.use("/", function(req, res) {
res.send("main page 2")
console.log("midddleware")
})
app.listen(3000)

如果您向服务器发出/的GET请求,Express将按照声明的顺序匹配路由,因此第一个匹配的路由是app.get()。它将用res.send("main page 1")发送响应,因为它不调用next(),所以所有路由都将完成,并且app.use("/", ...)永远不会被命中。

但是,如果您在浏览器中键入http://localhost:3000,这并不是浏览器发送给服务器的唯一请求。浏览器还将发送http://localhost:3000/favicon.ico(浏览器喜欢显示的网站图标(的请求。

app.get("/", ...)不会匹配该请求,但由于app.use()接受部分匹配(app.get()仅要求完全匹配(,/favicon.ico请求将由app.use("/", ..)匹配,您将看到您的console.log("middleware")。你不会看到res.send("main page 2")的结果,因为当浏览器请求favicon并返回一些纯文本时,它会忽略这一点,因为它显然不是它想要的图标。

如果您修改中间件以记录所请求的实际URL,那么一切都应该清楚:

app.use("/", function(req, res) {
res.send("main page 2")
console.log("midddleware", req.originalUrl);    // log the actual URL
})

请参阅中间件回调函数示例。它显示了这个例子:

var router = express.Router()
router.get('/', function (req, res, next) {
next()
})

如果您在第一个处理程序中调用next(),则将执行下一个处理程序。但请注意——在一个请求-响应周期中,您只能调用res.send一次。第二个会抛出一个错误,因为响应已经发送。

另请参阅编写中间件以获取更多示例:

中间件加载的顺序很重要:首先加载的中间件功能也会首先执行
如果在路由到根路径后加载myLogger,则请求永远不会到达该路径,并且应用程序不会打印"LOGGED",因为根路径的路由处理程序会终止请求-响应周期
中间件函数myLogger只需打印一条消息,然后通过调用next()函数将请求传递给堆栈中的下一个中间件函数。

最新更新