Express.jsのnext()を使用して次のミドルウェアに変数を渡す


200

さて、私の質問は、最初のミドルウェアから別のミドルウェアに変数を渡したいのですが、これを試してみましたが、「req.somevariable指定されたものが「未定義」である」とありました。


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

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

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

うまくいくはずです。質問のタイプミスでない限りres、ミドルウェア1に値を割り当て、ミドルウェア2から値を取得しようとするため、おそらく失敗しますreq
Andreas Hultgren 2013

Thankz @AndreasHultgren
user2791897

Local variables are available in middleware via req.app.locals expressjs.com/pt-br/api.html#app.locals
ロニーロイストン

回答:


202

変数をではreqなく、オブジェクトにアタッチしますres

の代わりに

res.somevariable = variable1;

持ってる:

req.somevariable = variable1;

他の人が指摘したように、res.localsミドルウェアを介してデータを渡す推奨される方法です。


13
res.locals.variable = var;を使用します。他の回答を参照してください
godzsa 2017年

1
変数を取得するには、次のミドルウェア関数でreq.res.locals.variableを使用します
William Wu

3
@WilliamWuそのres.localsではなくreq.res.locals
チェンバレン

2
res.locals.myVar行く方法です。
jasonseminara 2018年

448

これが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();
});

67
これが受け入れられない答えである理由がわからない。これは、リクエスト全体でミドルウェアから変数を設定するための文書化された方法です。
Sam Holmes

11
res.localsは、リクエストのライフサイクル中に最終的にレンダリングされるビューで使用することを目的としています。これがドキュメントに書かれています。ビューを使用していない場合、ローカルオブジェクトに物を置くのはやりすぎであり、慣例ではありません。これらの場合、Expressやリクエストライフサイクルなどの概念を学びながら認知負荷を軽減できるように、この規則を守るように人々に勧める傾向があります。
real_ate 2017

2
@real_ateはres.localsの主な使用方法ですが、OPの質問には対応していません。リクエストスコープの変数を将来のミドルウェアに渡すことが必要になる場合があります。私が思いついたのは、通常、下流のミドルウェアにルーティングされるクレームを設定する初期のミドルウェアでのユーザー認証の前後です。
チェンバレン2017

14
ミドルウェアを作成するためのエクスプレスドキュメントは、reqオブジェクトに変数を設定します。expressjs.com/en/guide/writing-middleware.html。セクションを見てくださいMiddleware function requestTime
ナマズ

3
@goonerifyは幸いにも応答が機能しない方法です。応答はres.json({})、などの応答オブジェクトの機能プロパティを呼び出すことによって送信されres.localsます。要求の存続期間中、バックエンドでのみ使用できます。 expressjs.com/en/5x/api.html
cchamberlain

22

のような変数を渡すことがベストプラクティスになるとは思いませんreq.YOUR_VARreq.YOUR_APP_NAME.YOUR_VARまたはを検討することをお勧めしreq.mw_params.YOUR_VARます。

他の属性の上書きを避けるのに役立ちます。

2020年5月31日更新

res.localsは探しているものであり、オブジェクトはリクエストをスコープとしています。

リクエストをスコープとするレスポンスローカル変数を含むオブジェクト。したがって、リクエスト/レスポンスサイクル(存在する場合)中にレンダリングされたビューでのみ使用できます。それ以外の場合、このプロパティはapp.localsと同じです。

このプロパティは、要求パス名、認証済みユーザー、ユーザー設定などの要求レベルの情報を公開するのに役立ちます。


2
req.YOUR_APP_NAME = {}最初に設定することをどのように提案しますか?まだ定義していないreq.YOUR_APP_NAME.someVarので、あなたがあなたに書こうとすると、エラーが発生しますreq.YOUR_APP_NAME
Kousha

2
@Koushaあなたは、ルーティングスクリプトの先頭にルータのミドルウェアを書くことができます:router.use(function(req,res,next){req.YOUR_APP_NAME = {};next()})
トマス

next()関数でそれをparamとして渡す方法はありますか?like next(myObj)
philx_x 2016年

1
@Kousha-未定義のエラーはExpressとは関係がなく、存在しないオブジェクトにプロパティを割り当てようとしています。通常、これを行うには、を使用しますreq.APP_NS = req.APP_NS || {}; req.APP_NS.somevar = 'value'
チェンバレン

1
@philx_x、next関数にパラメーターを渡すと、エクスプレスのエラーハンドラーがトリガーされてドロップアウトします。ドキュメントを確認してください。
MERL

7

reqresは2つの異なるオブジェクトであるためです。

追加したのと同じオブジェクトでプロパティを探す必要があります。


3

トリックは非常に簡単です...要求サイクルはまだかなり生きています。一時的に作成する新しい変数を追加するだけで、

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
}

1

上記のように、res.localsはこれを行うための(推奨される)良い方法です。Expressでこれを行う方法の簡単なチュートリアルについては、こちらを参照してください。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.