Übergeben von Variablen an die nächste Middleware mit next () in Express.js

200

Nun, meine Frage ist, dass ich eine Variable von der ersten Middleware an eine andere Middleware übergeben möchte, und ich habe versucht, dies zu tun, aber es gab " req.somevariableeine gegebene als 'undefiniert'".


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

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

////middleware2
...
some conditions
...
variable = req.somevariable;
...
user2791897
quelle
Sollte arbeiten. Wenn es sich nicht um einen Tippfehler in der Frage handelt, schlagen Sie wahrscheinlich fehl, weil Sie den Wert resin Middleware1 zuweisen und versuchen, ihn reqin Middleware2 abzurufen.
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

Antworten:

202

Hängen Sie Ihre Variable an das reqObjekt an, nichtres .

Anstatt

res.somevariable = variable1;

Haben:

req.somevariable = variable1;

Wie andere bereits betont haben, res.localswird empfohlen, Daten durch Middleware zu übertragen.

Amberlamps
quelle
13
benutze res.locals.variable = var; siehe die andere Antwort
godzsa
1
Um die Variable abzurufen, verwenden Sie req.res.locals.variable in der nächsten Middleware-Funktion
William Wu
3
@ WilliamWu sein res.locals, nicht req.res.locals.
Cchamberlain
2
res.locals.myVarist der Weg zu gehen.
Jasonseminara
446

Dafür ist das Objekt res.locals gedacht . Das Festlegen von Variablen direkt für das Anforderungsobjekt wird nicht unterstützt oder dokumentiert. res.locals garantiert den Status während der Laufzeit einer Anfrage.

res.locals

Ein Objekt, das lokale Antwortvariablen enthält, die für die Anforderung gültig sind und daher nur für die Ansichten verfügbar sind, die während dieses Anforderungs- / Antwortzyklus (falls vorhanden) gerendert wurden. Ansonsten ist diese Eigenschaft identisch mit app.locals.

Diese Eigenschaft ist nützlich, um Informationen auf Anforderungsebene wie den Namen des Anforderungspfads, den authentifizierten Benutzer, Benutzereinstellungen usw. bereitzustellen.

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

So rufen Sie die Variable in der nächsten Middleware ab:

app.use(function(req, res, next) {
    if (res.locals.authenticated) {
        console.log(res.locals.user.id);
    }
    next();
});
Kammerherr
quelle
66
Ich weiß nicht, warum dies nicht die akzeptierte Antwort ist. Dies ist die dokumentierte Methode zum Festlegen von Variablen aus der Middleware während einer Anfrage.
Sam Holmes
11
res.locals soll von Ansichten verwendet werden , die schließlich während des Lebenszyklus der Anforderung gerendert werden. Dies wird in der Dokumentation angegeben. Wenn Sie keine Ansichten verwenden, ist es übertrieben, Dinge auf das lokale Objekt zu setzen, und es ist nicht die Konvention. In diesen Fällen ermutige ich die Menschen, sich an die Konvention zu halten, damit wir die kognitive Belastung reduzieren können, während wir Konzepte wie Express lernen oder Lebenszyklen anfordern.
Real_ate
2
@real_ate, das ist die primäre Verwendung von res.locals, geht jedoch nicht auf die Frage des OP ein. Das Übergeben von Variablen mit Anforderungsbereich an zukünftige Middleware ist manchmal eine Notwendigkeit. Die Zeiten, in denen ich sie hatte, beziehen sich normalerweise auf die Benutzerauthentifizierung in einer frühen Middleware, die Ansprüche festlegt, die in einer nachgeschalteten Middleware weitergeleitet werden.
Cchamberlain
14
In der Expressdokumentation zum Schreiben von Middleware werden Variablen für das reqObjekt expressjs.com/de/guide/writing-middleware.html festgelegt . Schauen Sie sich den AbschnittMiddleware function requestTime
Catfish
2
@goonerify das ist zum Glück nicht so, wie die Antwort funktioniert. Antworten werden durch Aufrufen einer Funktionseigenschaft des Antwortobjekts übertragen, z. B. res.json({})usw., res.localsdie nur im Back-End über die Laufzeit der Anforderung verfügbar ist. expressjs.com/de/5x/api.html
cchamberlain
22

Ich denke nicht, dass die beste Vorgehensweise darin besteht, eine Variable wie zu übergeben req.YOUR_VAR. Vielleicht möchten Sie req.YOUR_APP_NAME.YOUR_VARoderreq.mw_params.YOUR_VAR .

Auf diese Weise können Sie vermeiden, dass andere Attribute überschrieben werden.

Update 31. Mai 2020

res.locals ist das, wonach Sie suchen. Das Objekt ist auf die Anforderung ausgerichtet.

Ein Objekt, das lokale Antwortvariablen enthält, die für die Anforderung gültig sind und daher nur für die Ansichten verfügbar sind, die während dieses Anforderungs- / Antwortzyklus (falls vorhanden) gerendert wurden. Ansonsten ist diese Eigenschaft identisch mit app.locals.

Diese Eigenschaft ist nützlich, um Informationen auf Anforderungsebene wie den Namen des Anforderungspfads, den authentifizierten Benutzer, Benutzereinstellungen usw. bereitzustellen.

Doron Segal
quelle
2
Wie schlagen Sie vor, req.YOUR_APP_NAME = {}zunächst einzustellen ? Wenn Sie nur versuchen, an req.YOUR_APP_NAME.someVarSie zu schreiben, wird eine Fehlermeldung req.YOUR_APP_NAMEangezeigt, die noch nicht definiert ist.
Kousha
2
@Kousha Sie können Router-Middleware oben in Ihrem Routing-Skript schreiben:router.use(function(req,res,next){req.YOUR_APP_NAME = {};next()})
Tomas
Gibt es eine Möglichkeit, es mit der next () -Funktion als param zu übergeben? wie nächstes (myObj)
philx_x
1
@Kousha - Ihr undefinierter Fehler hat nichts mit Express zu tun. Sie versuchen, einem nicht vorhandenen Objekt eine Eigenschaft zuzuweisen. Normalerweise würden Sie dazu verwenden req.APP_NS = req.APP_NS || {}; req.APP_NS.somevar = 'value'.
Cchamberlain
1
@philx_x, wenn Sie einen Parameter an nextfunction übergeben, wird der Express-Fehlerhandler ausgelöst und der Vorgang abgebrochen . Überprüfen Sie die Dokumente.
Merl
7

Das liegt daran requndres sind zwei verschiedene Objekte.

Sie müssen die Eigenschaft für dasselbe Objekt suchen, zu dem Sie sie hinzugefügt haben.

SLaks
quelle
3

Der Trick ist ziemlich einfach ... Der Anforderungszyklus ist noch ziemlich lebendig. Sie können einfach eine neue Variable hinzufügen, die einen temporären Aufruf erstellt

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

Da können Sie Ihre Anfrage in der ersten Middleware bearbeiten

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

In Middleware 1 behandeln Sie Ihre Logik und speichern Ihren Wert wie folgt:

req.anyvariable = yourvalue

In Middleware 2 können Sie diesen Wert von Middleware 1 wie folgt abrufen:

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

Wie oben erwähnt, ist res.locals eine gute (empfohlene) Möglichkeit, dies zu tun. Sehen Sie hier eine kurze Anleitung, wie man dies in Express zu tun.

nax3t
quelle