Express.js - 在应用程序级中间件中访问目标路由详细信息



>Background:

我有一个快速应用程序,其中包含一些简单的路由和路由器级中间件。我想注册一个应用程序级中间件。

问题所在

在路由器级中间件中。我可以访问req.route对象。但是我无法访问应用程序级中间件中的同一对象。 我可以理解这一点,因为在应用程序级中间件中,程序还没有在路由内。

但是有没有办法在全局中间件中获取req.route对象或等效于req.route.path的东西?

req.pathreq.originalUrl包含实际 URL,而不是路由路径。

const express = require('express');
const app = express();
const port = 3232;
app.use((req, res, next) => {
const route = req.route; // It is an application level middleware, route is null
return next(); 
});
app.get('/test/:someParams', (req, res) => {
const route = req.route; // can access req.route here because it is a Router-level middleware
console.log(route.path)
console.log(req.path)
return res.send('test')
});
app.listen(port, () => console.log(`Example app listening on port ${port}!`));

输出

请求:GET@localhost:3232/测试/33333

/test/33333 // I don't need this.
/test/:someParams // This is what I want to get inside the Application-Level Middleware 

替代解决方案

此问题的替代解决方案如下

const express = require('express');
const app = express();
const port = 3232;
function globalMiddleware(req, res, next) {
const route = req.route;
console.log(route) // can access it
return next();
}
app.use((req, res, next) => {
const route = req.route; // It is an application level middleware, route is null
return next();
});
app.get('/test/:someParams', globalMiddleware, (req, res) => {
const route = req.route; // can access req.route here because it is a Router-level middleware
});
app.listen(port, () => console.log(`Example app listening on port ${port}!`));

但是,将相同的中间件注入到我的每个和所有路由听起来不像是一个明智的解决方案。特别是在更大的应用程序上。

路由器对象的转储

{ 
"path":"/test/:someParams",
"stack":[ 
{ 
"name":"globalMiddleware",
"keys":[ 
],
"regexp":{ 
"fast_star":false,
"fast_slash":false
},
"method":"get"
},
{ 
"name":"<anonymous>",
"keys":[ 
],
"regexp":{ 
"fast_star":false,
"fast_slash":false
},
"method":"get"
}
],
"methods":{ 
"get":true
}
}

path钥匙是我想要得到的东西。请注意,req.route.pathreq.path不同

我也遇到了这个困难。我在互联网上找不到任何可以解决这个问题的东西,所以我试图搜索快速代码本身,以找到路线。基本上它与下面的代码相同,它查找哪个正则表达式对该路由有效。(谷歌翻译(

const url = req.originalUrl.split('?')[0] // Routes with query
const layer = req.app._router.stack.find(layer => {
return layer.regexp.exec(url) && layer.route
})

因此,您可以访问原始路径:

console.log(layer.route.path)

您希望在 req.route 中使用哪些数据?

您可以使用req.urlreq.methodreq.originalUrl等...

或者在应用程序级中间件中,您可以向对象添加新字段req

req.customRoute = {yourField: "yourValue"}此字段将在路由级中间件中可用

您可以根据请求使用中间件

const middleware = (req, res, next) => {
// Append what you want in req variable
req.route = "abc"  // let abc
req.path =  "path" // req.route.path
next();
}

你可以从中间件这里得到它

app.get('/test/:someParams', middleware, (req, res) => {
console.log(req.params.someParams)
console.log(req.route) // "abc"
console.log(req.path)  // "path"
});

对于应用级中间件

app.use((req, res, next) => {
req.route = "abc"  // let abc
req.path = "path" // or req.route.path
next()
})

最新更新