Express 路由器中间件在意外路由上被调用
Express router middleware gets called on unexpected routes
使用 express,我有多个路由需要一些中间件。它们不属于任何常见的 /url/path
.
Router-level middleware works in the same way as application-level middleware, except it is bound to an instance of express.Router()
据我所知,这意味着中间件仅适用于路由器实例的路由。但事实似乎并非如此。
在下面的示例中,我希望仅针对 http://localhost:10000/router
.
记录“router called”
但它也被记录为 http://localhost:10000/noRouter
,我不明白。为什么 router
实例的中间件 use
d 被直接添加到 app
的路由调用?是否可以创建一个 Router
以便只有绑定到 Router
的路由才能应用中间件?
const express = require('express')
const app = express()
const port = 10000
const router = express.Router();
router.use((req, _res, next) => {
console.log("router called")
next()
})
app.use(router)
router.get('/router', (req, res) => {
res.send("ok")
})
app.get('/noRouter', (req, res) => {
res.send("ok")
})
app.listen(port, () => {
console.log(`Listening at http://localhost:${port}`)
})
P.S.: 我没有被卡住,而是使用不同的方法让它工作。我只是想了解为什么这不起作用...
路由器刚刚插入到请求处理程序链中,并且 searched/executed 按顺序排列。
因为你这样做:
app.use(router)
您专门将所有请求发送到您的路由器。因此,所有请求都将通过该路由器中的各种处理程序,寻找与传入路径匹配的处理程序。这将包括您的 router.use()
中间件,它匹配所有路径,因此它将为发送到您的路由器的每个 URL 执行。路由器中没有逻辑会在执行任何中间件之前首先检查路由器中的某些路由是否匹配。在这方面,路由器就像 app
对象一样工作,并按照遇到它们的顺序执行中间件。所以,你的中间件不被执行的唯一方法是请求根本没有到达路由器。
如果您希望中间件仅应用于路由器中的路由,那么您有两种选择:
将路由器放在公共路径前缀上,例如:
app.use("/somerouterprefix", router);
然后,只有 URL 路由到您的路由器的 运行 路由器中的中间件。当然,这只会为以该前缀开头的路由执行中间件,但它也会为以该前缀开头的路由执行中间件,但在路由器中甚至没有匹配的路由处理程序。请记住,我之前说过,发送到路由器的所有内容都会导致您的中间件执行。
或者,其次,将中间件放在路由器中的每个单独的处理程序上,这样它只会在与路由器上的某些路由匹配时执行,例如:
const router = express.Router();
// give the middleware a function name so you can
// use it in specific route definitions
function myMiddleware((req, _res, next) => {
console.log("router called")
next()
});
// specify the middleware in your route definition
router.get('/router', myMiddleware, (req, res) => {
res.send("ok")
});
使用 express,我有多个路由需要一些中间件。它们不属于任何常见的 /url/path
.
Router-level middleware works in the same way as application-level middleware, except it is bound to an instance of express.Router()
据我所知,这意味着中间件仅适用于路由器实例的路由。但事实似乎并非如此。
在下面的示例中,我希望仅针对 http://localhost:10000/router
.
但它也被记录为 http://localhost:10000/noRouter
,我不明白。为什么 router
实例的中间件 use
d 被直接添加到 app
的路由调用?是否可以创建一个 Router
以便只有绑定到 Router
的路由才能应用中间件?
const express = require('express')
const app = express()
const port = 10000
const router = express.Router();
router.use((req, _res, next) => {
console.log("router called")
next()
})
app.use(router)
router.get('/router', (req, res) => {
res.send("ok")
})
app.get('/noRouter', (req, res) => {
res.send("ok")
})
app.listen(port, () => {
console.log(`Listening at http://localhost:${port}`)
})
P.S.: 我没有被卡住,而是使用不同的方法让它工作。我只是想了解为什么这不起作用...
路由器刚刚插入到请求处理程序链中,并且 searched/executed 按顺序排列。
因为你这样做:
app.use(router)
您专门将所有请求发送到您的路由器。因此,所有请求都将通过该路由器中的各种处理程序,寻找与传入路径匹配的处理程序。这将包括您的 router.use()
中间件,它匹配所有路径,因此它将为发送到您的路由器的每个 URL 执行。路由器中没有逻辑会在执行任何中间件之前首先检查路由器中的某些路由是否匹配。在这方面,路由器就像 app
对象一样工作,并按照遇到它们的顺序执行中间件。所以,你的中间件不被执行的唯一方法是请求根本没有到达路由器。
如果您希望中间件仅应用于路由器中的路由,那么您有两种选择:
将路由器放在公共路径前缀上,例如:
app.use("/somerouterprefix", router);
然后,只有 URL 路由到您的路由器的 运行 路由器中的中间件。当然,这只会为以该前缀开头的路由执行中间件,但它也会为以该前缀开头的路由执行中间件,但在路由器中甚至没有匹配的路由处理程序。请记住,我之前说过,发送到路由器的所有内容都会导致您的中间件执行。
或者,其次,将中间件放在路由器中的每个单独的处理程序上,这样它只会在与路由器上的某些路由匹配时执行,例如:
const router = express.Router();
// give the middleware a function name so you can
// use it in specific route definitions
function myMiddleware((req, _res, next) => {
console.log("router called")
next()
});
// specify the middleware in your route definition
router.get('/router', myMiddleware, (req, res) => {
res.send("ok")
});