在Express中间件中,req.locals、res.locals、res.data、req.data和app.locals有什么区别?

140

有一些类似的问题,但我的问题是如果我想传播我在不同路由中间件中获得的中间结果,最好的方法是什么?

app.use(f1); app.use(f2); app.use(f3);

function f1(req,res,next) {
  //some database queries are executed and I get results, say x1
  res.locals.dbResults = {...};
  next();
}

function f2(req,res,next) {
  // more processing based upon req.locals.dbResults 
  res.locals.moreResults = {....};
  next();
}
// ...

我认为可以使用req.locals在不同的中间件之间获得相同的数据传播。此外,请求和响应对象都将locals属性初始化为空对象在请求开始时。

另外,人们也可以设置res.mydata或req.mydata属性吗?

理论上,app.locals也可以用于通过不同的中间件传递此数据,因为它会跨中间件保持持续性,但这与app.locals的常规用法相反。它更多用于特定于应用程序的数据。还需要在请求响应周期结束时清除该数据,以便可以在下一个请求中使用相同的变量。

什么是通过中间件传播中间结果的最佳和标准方式?


相关 - https://dev59.com/31sW5IYBdhLWcg3wT155#35111195 - Manohar Reddy Poreddy
2个回答

215
正如您所提到的,可以使用req.localsres.locals或您自己定义的关键字 res.userData 。但是,在使用Express视图引擎时,您可以在中间件上设置res.locals上的中间数据,并且该数据将在视图中可用(请参见此帖子)。通常在中间件中设置请求级别的数据以避免覆盖res.locals中的视图数据,这是一种常见做法,尽管官方文档中没有记录。

res.locals 一个包含响应本地变量的对象,作用域限定于请求,因此仅在请求/响应周期中渲染的视图中可用(如果有的话)。否则,此属性与app.locals完全相同。

此属性非常适用于公开请求级别信息,例如请求路径名称、已验证的用户、用户设置等等。

来源:http://expressjs.com/en/api.html#res.locals


1
感谢您对文档区别的澄清,这有利于 res.locals。您确认了我的理解,理论上所有方法在技术上都是相同的。让我们等待更多的评论。我已经为您的答案点赞...肯定很有用。 - Sunny
1
顺便提一下:res.render() 优先于 res.locals。因此,有人可能会意外地覆盖变量,就像这样:res.locals = { name: 'Jake' } // later in code... res.render('user.template', { name: 'Tony' }, (err, html) => {}) // the 'name' variable is now 'Tony' - zenoh
2
无论如何,精心规划、干净整洁、模块化的中间件设计应该是比仅仅依赖单个对象键更好且更长期的解决方案。 - zenoh
1
req.locals(至少在TypeScript中)似乎不再存在,所以我想知道现在是否建议使用res.locals而不是使用req.locals? - Emile
1
在我看来,因为API调用者可以从请求调用中操作req.locals,所以最好将中间结果放在res.locals中。 - Yosua Lijanto Binar
1
请直接翻译以下与编程有关的内容:dont IMO,@YosuaLijantoBinar 如何修改调用者的req.local; 这将使req.locals对于路由处理程序数据传递不安全。 - droid192

1

在阅读Express文档时,我没有遇到req.locals,我甚至认为它不存在。

我的建议是使用res.locals来存储将要在视图中呈现的数据。

如果您想要存储自定义数据,请在res或req实例内创建一个属性(最好是数组或对象),例如req.data={},然后将您的数据存储在此“对象”中。


你的回答可以通过提供更多支持信息来改进。请编辑以添加进一步的细节,例如引用或文档,以便他人可以确认你的答案是正确的。您可以在帮助中心中找到有关如何编写良好答案的更多信息。 - Community

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