NodeJS 中间件调用顺序

时间:2021-05-30 12:11:53

标签: javascript node.js express

当我请求 res.send("main page 2") 时,为什么 res.send("main page 1") 不覆盖 localhost:3000
在 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)

2 个答案:

答案 0 :(得分:1)

您很可能被浏览器发送到您的服务器的第二个请求(针对 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") 的结果,因为当浏览器请求图标并返回一些纯文本时,它只会忽略它显然不是它要查找的图标。

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

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

答案 1 :(得分:0)

Middleware callback function examples。它显示了这个例子:

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

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

另见 Writing Middleware 以获取更多示例:

<块引用>

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

相关问题