【问题标题】:Passing variables to the next middleware using next() in Express.js在 Express.js 中使用 next() 将变量传递给下一个中间件
【发布时间】:2013-09-23 09:26:37
【问题描述】:

我想将一些变量从第一个中间件传递给另一个中间件,我尝试这样做,但出现“req.somevariable is a given as 'undefined'”。


//app.js
..
app.get('/someurl/', middleware1, middleware2)
...

////middleware1
...
some conditions
...
res.somevariable = variable1;
next();
...

////middleware2
...
some conditions
...
variable = req.somevariable;
...

【问题讨论】:

  • 应该可以。除非这是问题中的拼写错误,否则您可能会失败,因为您将值分配给 middleware1 中的 res 并尝试从 middleware2 中的 req 获取它。
  • 谢谢@AndreasHultgren
  • Local variables are available in middleware via req.app.locals expressjs.com/pt-br/api.html#app.locals

标签: javascript node.js express middleware next


【解决方案1】:

这就是 res.locals 对象的用途。不支持或记录直接在请求对象上设置变量。 res.locals 保证在请求的生命周期内保持状态。

res.locals

一个对象,其中包含范围为 请求,因此仅可用于期间呈现的视图 该请求/响应周期(如果有)。否则,此属性为 与 app.locals 相同。

此属性对于公开请求级信息很有用,例如 请求路径名、认证用户、用户设置等。

app.use(function(req, res, next) {
    res.locals.user = req.user;  
    res.locals.authenticated = !req.user.anonymous;
    next();
});

在下一个中间件中检索变量:

app.use(function(req, res, next) {
    if (res.locals.authenticated) {
        console.log(res.locals.user.id);
    }
    next();
});

【讨论】:

  • 不知道为什么这不是公认的答案,这是在整个请求中从中间件设置变量的记录方法。
  • res.locals 旨在供 views 使用,最终在请求的生命周期中呈现,这就是文档所说的。如果您不使用视图,则将内容放在 locals 对象上是矫枉过正的,这 不是 约定。在这些情况下,我倾向于鼓励人们遵守约定,这样我们就可以在学习 Express 或请求生命周期等概念的同时减少认知负担。
  • @real_ate 这是 res.locals 的主要用途,但它没有解决 OPs 问题。将请求范围的变量传递给未来的中间件有时是必要的,我遇到它的时候通常是围绕早期中间件中的用户身份验证,该中间件设置在下游中间件中路由的声明。
  • 用于编写中间件的快速文档在req 对象expressjs.com/en/guide/writing-middleware.html 上设置变量。看Middleware function requestTime部分
  • @goonerify 幸运的是,这不是响应的工作方式。响应是通过调用响应对象的功能属性来传输的,例如res.json({}) 等。res.locals 仅在请求的生命周期内在后端可用。 expressjs.com/en/5x/api.html
【解决方案2】:

将您的变量附加到 req 对象,而不是 res

代替

res.somevariable = variable1;

有:

req.somevariable = variable1;

正如其他人所指出的,res.locals 是通过中间件传递数据的推荐方式。

【讨论】:

  • 使用 res.locals.variable = var;查看其他答案
  • 获取变量,在下一个中间件函数中使用req.res.locals.variable
  • @WilliamWu 是 res.locals,而不是 req.res.locals
  • res.locals.myVar 是要走的路。
  • 抱歉问,但现在我很困惑。这是矛盾的答案吗。首先你建议使用req.somevariable = variable1;,然后你建议使用res.locals。如果有人可以更好地解释我,也许我错过了什么?
【解决方案3】:

我认为最佳实践不会传递像req.YOUR_VAR 这样的变量。您可能需要考虑req.YOUR_APP_NAME.YOUR_VARreq.mw_params.YOUR_VAR

它将帮助您避免覆盖其他属性。

2020 年 5 月 31 日更新

res.locals 是您要查找的内容,该对象的范围为请求。

一个对象,其中包含范围为请求的响应局部变量,因此仅可用于在该请求/响应周期(如果有)期间呈现的视图。否则,此属性与 app.locals 相同。

此属性对于公开请求级信息很有用,例如请求路径名称、经过身份验证的用户、用户设置等。

【讨论】:

  • 您建议如何初始设置req.YOUR_APP_NAME = {}?您只需尝试写信给req.YOUR_APP_NAME.someVar,您将收到一个错误,因为req.YOUR_APP_NAME 尚未定义。
  • @Kousha 您可以在路由脚本的顶部编写路由器中间件:router.use(function(req,res,next){req.YOUR_APP_NAME = {};next()})
  • 有没有办法通过 next() 函数将其作为参数传递?喜欢下一个(myObj)
  • @Kousha - 您的未定义错误与 express 无关,您试图将属性分配给不存在的对象。通常要做到这一点,你会使用req.APP_NS = req.APP_NS || {}; req.APP_NS.somevar = 'value'
  • @philx_x,如果您将任何参数传递给next 函数,它将触发 express 的错误处理程序并退出。检查文档。
【解决方案4】:

那是因为reqres 是两个不同的对象。

您需要在添加它的同一对象上查找该属性。

【讨论】:

    【解决方案5】:

    诀窍很简单......请求周期仍然非常活跃。您可以添加一个新变量,该变量将创建一个临时调用

    app.get('some/url/endpoint', middleware1, middleware2);
    

    因为您可以在第一个中间件中处理您的请求

    (req, res, next) => {
        var yourvalue = anyvalue
    }
    

    在中间件 1 中,您处理逻辑并存储您的值,如下所示:

    req.anyvariable = yourvalue
    

    在中间件 2 中,您可以通过执行以下操作从中间件 1 中获取此值:

    (req, res, next) => {
        var storedvalue = req.yourvalue
    }
    

    【讨论】:

      【解决方案6】:

      如上所述, res.locals 是一种很好的(推荐的)方法。有关如何在 Express 中执行此操作的快速教程,请参阅 here

      【讨论】:

        猜你喜欢
        • 2016-03-25
        • 1970-01-01
        • 1970-01-01
        • 2017-08-17
        • 1970-01-01
        • 2020-08-26
        • 1970-01-01
        • 1970-01-01
        • 2015-05-22
        相关资源
        最近更新 更多