Passando variáveis ​​para o próximo middleware usando next () no Express.js

200

Bem, minha pergunta é: eu quero passar alguma variável do primeiro middleware para outro middleware, e tentei fazer isso, mas havia " req.somevariableé dado como 'indefinido'".


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

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

////middleware2
...
some conditions
...
variable = req.somevariable;
...
user2791897
fonte
Deveria trabalhar. A menos que seja um erro de digitação na pergunta, você provavelmente falha porque atribui o valor ao resmiddleware1 e tenta obtê-lo reqno middleware2.
Andreas Hultgren
Obrigado, @AndreasHultgren
user2791897
Local variables are available in middleware via req.app.locals expressjs.com/pt-br/api.html#app.locals
Ronnie Royston

Respostas:

202

Anexe sua variável ao reqobjeto, não res.

Ao invés de

res.somevariable = variable1;

Ter:

req.somevariable = variable1;

Como outros já apontaram, res.localsé a maneira recomendada de passar dados pelo middleware.

Amberlamps
fonte
13
use res.locals.variable = var; Veja a outra resposta
godzsa 10/03/2017
1
para recuperar a variável, o uso req.res.locals.variable na próxima função middleware
William Wu
3
@WilliamWu its res.locals, not req.res.locals.
Cchamberlain
2
res.locals.myVaré o caminho a percorrer.
Jasonseminara 23/03/19
448

É para isso que serve o objeto res.locals . A definição de variáveis ​​diretamente no objeto de solicitação não é suportada ou documentada. É garantido que o res.locals mantém o estado durante a vida útil de uma solicitação.

res.locals

Um objeto que contém variáveis ​​locais de resposta com escopo definido para a solicitação e, portanto, disponível apenas para as visualizações renderizadas durante esse ciclo de solicitação / resposta (se houver). Caso contrário, essa propriedade é idêntica a app.locals.

Essa propriedade é útil para expor informações no nível da solicitação, como o nome do caminho da solicitação, usuário autenticado, configurações do usuário etc.

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

Para recuperar a variável no próximo middleware:

app.use(function(req, res, next) {
    if (res.locals.authenticated) {
        console.log(res.locals.user.id);
    }
    next();
});
cchamberlain
fonte
67
Não sei por que essa não é a resposta aceita, é a maneira documentada de definir variáveis ​​do middleware durante uma solicitação.
Sam Holmes
11
O res.locals deve ser usado por visualizações que são renderizadas eventualmente durante o ciclo de vida da solicitação, é o que a documentação está dizendo. Se você não estiver usando pontos de vista que é um exagero para colocar as coisas no objeto habitantes e é não a convenção. Nesses casos, tenho a tendência de incentivar as pessoas a seguir a convenção para que possamos reduzir a carga cognitiva enquanto aprendemos conceitos como o Express ou solicitamos ciclos de vida.
real_ate 21/02
2
@real_ate que é o uso principal de res.locals, no entanto, ele não aborda a questão dos OPs. A passagem de variáveis ​​com escopo de solicitação para o middleware futuro às vezes é uma necessidade, o momento em que o fiz foi surgir tipicamente em torno da autenticação do usuário em um middleware inicial, que define reivindicações que são roteadas em um middleware downstream.
Cchamberlain 21/02
14
A documentação expressa para escrever middleware define variáveis ​​no reqobjeto expressjs.com/en/guide/writing-middleware.html . Veja a seçãoMiddleware function requestTime
Peixe
3
Felizmente, @goonerify não é como a resposta funciona. As respostas são transmitidas chamando uma propriedade funcional do objeto de resposta como res.json({}), etc., res.localsestá disponível apenas no back-end durante a vida útil da solicitação. expressjs.com/en/5x/api.html
cchamberlain
22

Eu não acho que as melhores práticas passem por uma variável como req.YOUR_VAR. Você pode querer considerar req.YOUR_APP_NAME.YOUR_VARou req.mw_params.YOUR_VAR.

Isso ajudará a evitar a substituição de outros atributos.

Atualização 31 de maio de 2020

res.locals é o que você está procurando, o objeto está no escopo da solicitação.

Um objeto que contém variáveis ​​locais de resposta com escopo definido para a solicitação e, portanto, disponível apenas para as visualizações renderizadas durante esse ciclo de solicitação / resposta (se houver). Caso contrário, essa propriedade é idêntica a app.locals.

Essa propriedade é útil para expor informações no nível da solicitação, como o nome do caminho da solicitação, usuário autenticado, configurações do usuário etc.

Doron Segal
fonte
2
Como você sugere definir req.YOUR_APP_NAME = {}inicialmente? Você apenas tenta escrever para req.YOUR_APP_NAME.someVarvocê receberá um erro como req.YOUR_APP_NAMEainda não está definido.
Kousha
2
@Kousha Você pode escrever o middleware do roteador na parte superior do seu script de roteamento:router.use(function(req,res,next){req.YOUR_APP_NAME = {};next()})
Tomas
existe uma maneira de passá-lo como param com a próxima função ()? como próximo (myObj)
philx_x 14/06
1
@ Kousha - Seu erro indefinido não tem nada a ver com o express, é você tentando atribuir uma propriedade a um objeto que não existe. Normalmente, para fazer isso, você usaria req.APP_NS = req.APP_NS || {}; req.APP_NS.somevar = 'value'.
Cchamberlain
1
@philx_x, se você passar algum parâmetro para nextfuncionar, ele acionará o 'manipulador de erros express' e sairá. verifique os documentos.
Merl
7

Isso porque reqe ressão dois objetos diferentes.

Você precisa procurar a propriedade no mesmo objeto em que a adicionou.

SLaks
fonte
3

O truque é bem simples ... O ciclo de solicitações ainda está vivo. Você pode simplesmente adicionar uma nova variável que criará uma chamada temporária

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

Como você pode lidar com sua solicitação no primeiro middleware

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

No middleware 1, você lida com sua lógica e armazena seu valor como abaixo:

req.anyvariable = yourvalue

No middleware 2, você pode pegar esse valor no middleware 1, fazendo o seguinte:

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

Como mencionado acima, res.locals é uma boa maneira (recomendada) de fazer isso. Veja aqui um tutorial rápido sobre como fazer isso no Express.

nax3t
fonte