Pasar variables al siguiente middleware usando next () en Express.js

200

Bueno, mi pregunta es si quiero pasar alguna variable del primer middleware a otro middleware, e intenté hacer esto, pero hubo " req.somevariabledado como 'indefinido'".


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

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

////middleware2
...
some conditions
...
variable = req.somevariable;
...
usuario2791897
fuente
Deberia trabajar. A menos que sea un error tipográfico en la pregunta, probablemente falle porque asigna el valor a resen middleware1 e intenta obtenerlo reqen middleware2.
Andreas Hultgren
Thankz @AndreasHultgren
user2791897
Local variables are available in middleware via req.app.locals expressjs.com/pt-br/api.html#app.locals
Ronnie Royston

Respuestas:

202

Adjunte su variable al reqobjeto, no res.

En vez de

res.somevariable = variable1;

Tener:

req.somevariable = variable1;

Como otros han señalado, res.localses la forma recomendada de pasar datos a través de middleware.

Lámparas de color ambar
fuente
13
use res.locals.variable = var; ver la otra respuesta
godzsa
1
para recuperar la variable, use req.res.locals.variable en la próxima función de middleware
William Wu
3
@WilliamWu es res.locals, no req.res.locals.
cchamberlain
2
res.locals.myVarEs el camino a seguir.
jasonseminara 23/0318
449

Para eso está el objeto res.locals . La configuración de variables directamente en el objeto de solicitud no es compatible ni está documentada. res.locals está garantizado para mantener el estado durante la vida de una solicitud.

res.locals

Un objeto que contiene variables locales de respuesta en el ámbito de la solicitud y, por lo tanto, solo está disponible para las vistas representadas durante ese ciclo de solicitud / respuesta (si corresponde). De lo contrario, esta propiedad es idéntica a app.locals.

Esta propiedad es útil para exponer información a nivel de solicitud, como el nombre de la ruta de solicitud, el usuario autenticado, la configuración del usuario, etc.

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

Para recuperar la variable en el siguiente middleware:

app.use(function(req, res, next) {
    if (res.locals.authenticated) {
        console.log(res.locals.user.id);
    }
    next();
});
cchamberlain
fuente
67
No sé por qué esta no es la respuesta aceptada, esta es la forma documentada de establecer variables del middleware a lo largo de una solicitud.
Sam Holmes
11
res.locals está destinado a ser utilizado por vistas que finalmente se representan durante el ciclo de vida de la solicitud, esto es lo que dice la documentación. Si no está utilizando puntos de vista que es un exceso para poner las cosas en el objeto locales y es no la convención. En estos casos, tiendo a alentar a las personas a seguir la convención para que podamos reducir la carga cognitiva mientras aprendemos conceptos como Express o solicitar ciclos de vida.
real_ate
2
@real_ate que es el uso principal de res.locals, sin embargo, no aborda la pregunta de OP. En ocasiones, es necesario pasar las variables con ámbito de solicitud a un middleware futuro, las veces que he tenido que hacerlo generalmente se refieren a la autenticación del usuario en un middleware temprano que establece reclamos que se enrutan en un middleware posterior.
cchamberlain
14
La documentación expresa para escribir middleware establece variables en el reqobjeto expressjs.com/en/guide/writing-middleware.html . Mire la secciónMiddleware function requestTime
Bagre
3
@goonerify afortunadamente no es así como funciona la respuesta. Las respuestas se transmiten llamando a una propiedad funcional del objeto de respuesta como res.json({}), por ejemplo , etc., res.localssolo está disponible en el back-end durante la vida de la solicitud. expressjs.com/en/5x/api.html
cchamberlain
22

No creo que la mejor práctica sea pasar una variable como req.YOUR_VAR. Es posible que desee considerar req.YOUR_APP_NAME.YOUR_VARo req.mw_params.YOUR_VAR.

Le ayudará a evitar sobrescribir otros atributos.

Actualización 31 de mayo de 2020

res.locals es lo que está buscando, el objeto está limitado a la solicitud.

Un objeto que contiene variables locales de respuesta en el ámbito de la solicitud y, por lo tanto, solo está disponible para las vistas representadas durante ese ciclo de solicitud / respuesta (si corresponde). De lo contrario, esta propiedad es idéntica a app.locals.

Esta propiedad es útil para exponer información a nivel de solicitud, como el nombre de la ruta de solicitud, el usuario autenticado, la configuración del usuario, etc.

Doron Segal
fuente
2
¿Cómo sugiere configurar req.YOUR_APP_NAME = {}inicialmente? Solo intente escribirle y req.YOUR_APP_NAME.someVarrecibirá un error que req.YOUR_APP_NAMEaún no está definido.
Kousha
2
@Kousha Puede escribir middleware de enrutador en la parte superior de su secuencia de comandos de enrutamiento:router.use(function(req,res,next){req.YOUR_APP_NAME = {};next()})
Tomás
¿Hay alguna manera de pasarlo como parámetro con la función next ()? like next (myObj)
philx_x
1
@Kousha: su error indefinido no tiene nada que ver con express, está tratando de asignar una propiedad a un objeto que no existe. Por lo general, para hacer esto usarías req.APP_NS = req.APP_NS || {}; req.APP_NS.somevar = 'value'.
cchamberlain
1
@philx_x, si pasa algún parámetro a la nextfunción, activará el controlador de error express y se desconectará. revisa los documentos.
Merl
7

Eso es porque reqy resson dos objetos diferentes.

Debe buscar la propiedad en el mismo objeto al que la agregó.

SLaks
fuente
3

El truco es bastante simple ... El ciclo de solicitud sigue vivo. Simplemente puede agregar una nueva variable que creará una llamada temporal

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

Como puede manejar su solicitud en el primer middleware

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

En el middleware 1 maneja su lógica y almacena su valor como a continuación:

req.anyvariable = yourvalue

En el middleware 2 puede capturar este valor del middleware 1 haciendo lo siguiente:

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

Como se mencionó anteriormente, res.locals es una buena forma (recomendada) de hacer esto. Vea aquí un tutorial rápido sobre cómo hacer esto en Express.

nax3t
fuente