当我请求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()
函数将请求传递给堆栈中的下一个中间件函数。