修改 Express.js 请求对象

44
在express.js中,我想为我的每个URI侦听器提供一个额外的属性,用于提供协议、主机名和端口号。例如:
app.get('/users/:id', function(req, res) {
  console.log(req.root); // https://12.34.56.78:1324/
});

我当然可以将req.protocol、req.host连接起来,然后在每个URI监听器中传递端口号(似乎缺少req对象),但我想以一种方式完成它,使它们所有人都能够访问这些信息。

此外,主机名可能因请求而异(机器具有多个接口),因此我不能只是在应用程序启动时连接此字符串。

目标是向使用者提供指向此API中更多资源的URI。

有没有一种方法告诉Express我想要req对象具有这些附加信息?有没有比我正在概述的更好的方法?

5个回答

77

您可以添加自定义中间件,为每个请求设置属性:

app.use(function (req, res, next) {
    req.root = req.protocol + '://' + req.get('host') + '/';
    next();
});

使用req.get获取Host头,如果需要的话,它应该包括端口号。

只需确保在以下代码之前添加它:

app.use(app.router);

@AdamPietrasiak 这不是常量,如果您有多个域名(例如“your-app.com”,“your-app.com.ar”和“your-app.com.br”),则需要为每个请求检查域名。 - Sebastian Gabriel Vinci
app.router已经过时了,顺便提一下。 - Thecave3

37

您可以扩展express.request原型。


类似 require("express").request.prototype.foo = function(){} 的代码? - redben
除非https的根属性永远不会改变,否则在这种情况下不适用于扩展express.request,否则您需要使用中间件并获取req.protocol...无论如何,如果您想扩展请求(这实际上是我找到这个问题的原因),只需使用express.request.getFooParam = function() {return this.param('foo');} - neiker
正是我正在寻找的。已登录以点赞,无需中间件,当你可以到根并扩展原型时。 - Nelo Mitranim

9
最好的修改请求对象的方法是在app.router声明之前添加自己的中间件函数。
    app.use(function(req, res, next){
      // Edit request object here
      req.root = 'Whatever I want';
      next();
    });
    app.use(app.router);

这将修改请求对象,每个路由都能够访问 req.root 属性,因此:
    app.get('/',function(req, res, next){
      console.log(req.root); // will print "Whatever I want";
    });

4
你可以使用中间件。将以下内容添加到你的app.configure块内:
app.use(function (req, res, next) {
  req.root = 'WHAT YOU WANT';
  next();
});

每个请求都会通过此函数,然后由 next() 转到正确的url-block。


1
Express旨在支持响应对象中的自定义变量,而不是请求对象。响应对象支持在res.locals中设置自定义变量。请参见http://expressjs.com/en/4x/api.html#res.locals。对于TypeScript用户来说,这特别有用。 locals属性类型为Record<string, any>

这与问题无关。我们正在寻找修改请求对象的方法。 - olegario
1
res.locals 表示它用于模板渲染... 例如 PassportJS,会更新请求以添加用户字段,因此这绝对不正确。 - OneCricketeer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接