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

时间:2019-09-09 13:28:59

标签: javascript node.js express middleware

背景:

我有一个带有一些简单路由和路由器级中间件的快速应用程序。我要注册一个应用程序级中间件。

问题

在路由器级中间件中。我可以访问structure(list(x = c(0, 1, 1, 2), y = c(1, 1, 1, 2), z = c(1, 1, 0, 2), d = c(0, 0, 0, 2), e = c(1, 2, 2, 2)), class = "data.frame", row.names = c(NA, -4L)) 对象。但是我无法在应用程序级中间件中访问同一对象。 我能理解这一点,因为在应用程序级中间件内部,该程序还不在路由之内。

但是,有什么方法可以在全局中间件中获取req.route对象或与req.route等效的东西吗?

req.route.pathreq.path包含真实网址,而不是路由路径。

示例

req.originalUrl

输出

请求:GET @ localhost:3232 / test / 33333

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}!`));

替代解决方案

此问题的另一种解决方案可以如下所示

/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 } } 键是我想要的东西。请注意,pathreq.route.path

不同

3 个答案:

答案 0 :(得分:1)

我也有这个困难。我在互联网上找不到能解决问题的任何东西,因此我尝试搜索快递代码本身,以查找路线。基本上,它与下面的代码相同,它查找对于该路由有效的regexp。 (Google翻译)

This div has calculated width 300px for some reason
<div class="top">
  <div class="grid-container" key="1">
    <svg class="svg" viewBox="-10 -10 20 20" preserveAspectRatio="none">
      <polygon id="diamond" strokeWidth="0" fill="yellow" points="0,-10 10,0 0,10 -10,0" />
    </svg>
    <div class="content">
      ab
    </div>
  </div>
  <!-- more grid-containers -->
</div>

This works as expected
<div class="top">
  <div class="grid-container">
    <svg class="svg" viewBox="-10 -10 20 20" preserveAspectRatio="none">
      <polygon strokeWidth="0" fill="yellow" points="0,-10 10,0 0,10 -10,0" />
    </svg>
    <div class="content">
      abcdefghijkl
    </div>
  </div>
  <!-- more grid-containers -->
</div>

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

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

答案 1 :(得分:0)

您希望在req.route中获得哪些数据?

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

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

req.customRoute = {yourField: "yourValue"} 并且该字段将在路由级中间件中提供

答案 2 :(得分:-1)

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

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()
})