在 Express.js 中使用 next() 将变量传递给下一个中间件

IT技术 javascript node.js express middleware next
2021-03-04 03:41:05

我想将一些变量从第一个中间件传递给另一个中间件,我尝试这样做,但有“req.somevariable给定为‘未定义’”。


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

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

////middleware2
...
some conditions
...
variable = req.somevariable;
...
6个回答

这就是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();
});
不知道为什么这不是公认的答案,这是整个请求中从中间件设置变量记录方法。
2021-05-06 03:41:05
编写中间件的 express 文档在req对象expressjs.com/en/guide/writing-middleware.html上设置变量看栏目Middleware function requestTime
2021-05-11 03:41:05
@goonerify 幸运的是,这不是响应的工作原理。响应是通过调用响应对象的功能属性(例如res.json({})res.locals传输的仅在请求的整个生命周期内在后端可用。 expressjs.com/en/5x/api.html
2021-05-12 03:41:05
res.locals 旨在供最终在请求生命周期中呈现视图使用,这就是文档所说的。如果您不使用视图,将东西放在 locals 对象上是多余的,这不是惯例。在这些情况下,我倾向于鼓励人们遵守约定,这样我们就可以在学习 Express 或请求生命周期等概念的同时减少认知负担。
2021-05-13 03:41:05
@real_ate 这是 res.locals 的主要用途,但它没有解决 OP 问题。将请求范围的变量传递给未来的中间件有时是必要的,我遇到它的时候通常是在早期中间件中的用户身份验证周围,该中间件设置在下游中间件中路由的声明。
2021-05-14 03:41:05

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

代替

res.somevariable = variable1;

有:

req.somevariable = variable1;

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

很抱歉问这个问题,但现在我很困惑。这是自相矛盾的答案。首先你建议这样做req.somevariable = variable1;,然后你建议使用res.locals. 也许我错过了一些东西,如果有人能更好地解释我吗?
2021-04-26 03:41:05
@WilliamWu 它的res.locals,不是req.res.locals
2021-05-04 03:41:05
res.locals.myVar 是要走的路。
2021-05-06 03:41:05
要检索变量,请在下一个中间件函数中使用 req.res.locals.variable
2021-05-10 03:41:05
使用 res.locals.variable = var; 看另一个答案
2021-05-12 03:41:05

我认为最佳实践不会传递像req.YOUR_VAR. 您可能要考虑req.YOUR_APP_NAME.YOUR_VARreq.mw_params.YOUR_VAR

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

2020 年 5 月 31 日更新

res.locals是你要找的,对象的范围是请求。

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

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

@Kousha - 您未定义的错误与 express 无关,而是您试图将属性分配给不存在的对象。通常要做到这一点,您将使用req.APP_NS = req.APP_NS || {}; req.APP_NS.somevar = 'value'.
2021-04-17 03:41:05
@philx_x,如果你向next函数传递任何参数,它会触发 express 的错误处理程序并退出。检查文档。
2021-04-21 03:41:05
req.YOUR_APP_NAME = {}最初建议如何设置你只是尝试写信给req.YOUR_APP_NAME.someVar你会得到一个req.YOUR_APP_NAME尚未定义的错误
2021-05-05 03:41:05
@Kousha 您可以在路由脚本的顶部编写路由器中间件: router.use(function(req,res,next){req.YOUR_APP_NAME = {};next()})
2021-05-13 03:41:05
有没有办法用 next() 函数将它作为参数传递?像下一个(myObj)
2021-05-14 03:41:05

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

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

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

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
}