簡體   English   中英

在 Express.js 中使用 next() 將變量傳遞給下一個中間件

[英]Passing variables to the next middleware using next() in Express.js

我想將一些變量從第一個中間件傳遞給另一個中間件,我嘗試這樣做,但是有“ req.somevariable is a given as 'undefined'”。


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

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

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

這就是res.locals object 的用途。 不支持或記錄直接在請求 object 上設置變量。 res.locals保證在請求的生命周期內保持 state 。

res.locals (注意:此處引用的文檔現已過時,請查看最新版本的鏈接。)

一個 object 包含范圍為請求的響應局部變量,因此僅可用於在該請求/響應周期(如果有)期間呈現的視圖。 否則,此屬性與 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(); });

將您的變量附加到req object,而不是res

代替

res.somevariable = variable1;

有:

 req.somevariable = variable1;

正如其他人指出的那樣, res.locals是通過中間件傳遞數據的推薦方式。

我認為最佳實踐不會傳遞像req.YOUR_VAR這樣的變量。 您可能需要考慮req.YOUR_APP_NAME.YOUR_VARreq.mw_params.YOUR_VAR

它將幫助您避免覆蓋其他屬性。

將變量傳遞給其他中間件和端點函數的最常見模式是將值附加到請求 object req

在你的情況下,這意味着有這樣的中間件:

 app.use(function (req, res, next) { req.someVariable = 123; next(); }); app.use(function (req, res, next) { console.log("The variable is", req.someVariable); next(); });

這種模式有很多常見的用例,是快遞社區的標准做法。 參見,例如:


值得注意的是,目前投票率最高的答案錯誤地建議為此目的使用res.locals ——這似乎源於對文檔的誤讀。 出於這個原因,我將詳細說明為什么這不是解決問題的常用方法(盡管它也不是特別有害)。

文檔

作為res.locals方法適合該案例的支持證據,引用現已過時的文檔

一個 object 包含范圍為請求的響應局部變量,因此僅可用於在該請求/響應周期(如果有)期間呈現的視圖。 否則,此屬性與 app.locals 相同。

此屬性對於公開請求級信息(例如請求路徑名、經過身份驗證的用戶、用戶設置等)很有用。

請注意此處的框架: res.locals僅適用於“在該請求期間呈現的視圖”可用的變量(已添加重點)。

這就是res.locals涉及的。 res.render使用一些給定的數據以及對本地的訪問來呈現一些模板文件。 這實際上在v2 文檔中更加清晰, 我們現在更新當前的 Express 文檔,使其更加清晰:

使用此屬性設置可在使用 res.render 呈現的模板中訪問的變量。 res.locals 上設置的變量在單個請求-響應周期內可用,並且不會在請求之間共享。

為了保留局部變量以用於請求之間的模板渲染,請改用 app.locals。

此屬性對於向應用程序中呈現的模板公開請求級信息(例如請求路徑名稱、經過身份驗證的用戶、用戶設置等)很有用。

(強調補充。)

導游

擴展req成為標准方法的進一步證據可在編寫中間件指南中找到,該指南指出:

接下來,我們將創建一個名為“requestTime”的中間件 function,並向請求 object 添加一個名為 requestTime 的屬性。

 const requestTime = function (req, res, next) { req.requestTime = Date.now() next() }

當在這個問題的答案的討論中提到這一點時,一位用戶回答說:“這是在他們添加 res.locals 之前你會這樣做的方式,所以可能是舊文檔。 res.locals 是專門為此而設計的命名空間。 "

但是,這與代碼庫的歷史不相符:本地人自 v2 以來就存在,這明顯早於express.json包含在庫中,此時更改行為是有意義的,如果它在res.locals中保存值確實是正確的。

結束語

在評論中寫道但被忽視的@real_ate 大喊

那是因為reqres是兩個不同的對象。

您需要在添加它的同一個 object 上查找該屬性。

訣竅很簡單......請求周期仍然非常活躍。 您可以添加一個新變量,該變量將創建一個臨時調用

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 }

此示例應用程序使用 requestTime 中間件 function,它在req上設置值requestTime

端點 function for /使用中間件 function 添加到req (請求對象)的屬性。

 var express = require('express') var app = express() var requestTime = function (req, res, next) { req.requestTime = Date.now() next() } app.use(requestTime) app.get('/', function (req, res) { var responseText = 'Hello World:<br>' responseText += '<small>Requested at. ' + req.requestTime + '</small>' res.send(responseText) }) app listen(3000)

如上所述, res.locals 是一個很好的(推薦的)方法來做到這一點。 有關如何在 Express 中執行此操作的快速教程,請參見此處

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM