23

对于只需要在单个请求期间可用的数据,应该将其存储在哪里?我正在 req 和 res 对象上创建新属性,因此我不必将该数据从函数传递到函数。

req.myNewValue = 'just for this request'

进程对象是一个选项吗?还是在所有请求中全局共享?

4

4 回答 4

32

在 Express 4 中,最佳实践是将请求级别的变量存储在res.locals上。

一个对象,其中包含范围为请求的响应局部变量,因此仅可用于在该请求/响应周期(如果有)期间呈现的视图。否则,此属性与 app.locals 相同。

此属性对于公开请求级信息(例如请求路径名、经过身份验证的用户、用户设置等)很有用。

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

process对象由所有请求共享,不应按请求使用。

于 2017-01-06T20:10:11.837 回答
21

如果您正在谈论像这里一样传递的变量:

http.createServer(function (req, res) {
    req.myNewValue = 'just for this request';
    res.writeHead(200, {'Content-Type': 'text/plain'});
    res.end('Hello World\n');
}).listen(1337, '127.0.0.1');

那么你在做什么就很好了。req存储请求数据,您可以根据需要对其进行修改。如果您使用的是 Express 之类的框架,那么它也应该没问题(请记住,您可能会覆盖对象的一些内置属性req)。

如果通过“进程对象”您指的是全局变量process,那么绝对不是。这里的数据是全局的,根本不应该修改。

于 2012-06-11T15:54:48.503 回答
2

如果您想在异步回调中保留数据,并且可能存在请求和响应对象不可用的情况。所以在这种情况下continuation-local-storage包是有帮助的。

它用于从不易访问的点访问数据或当前的快速请求/响应。它使用了命名空间的概念。

这是我如何设置的

安装continuation-local-storage

npm install continuation-local-storage --save

创建命名空间

let app = express();
let cls = require('continuation-local-storage');
let namespace = cls.createNamespace('com.domain');

然后是中间件

app.use((req, res, next) => {
   var namespace = cls.getNamespace('com.domain');
   // wrap the events from request and response
   namespace.bindEmitter(req);
   namespace.bindEmitter(res);

   // run following middleware in the scope of the namespace we created
   namespace.run(function () {
      // set data on the namespace, makes it available for all continuations
      namespace.set('data', "any_data");
      next();
   });
})

现在在任何文件或函数中,您都可以获取此命名空间并使用其中保存的数据

//logger.ts

var getNamespace = require("continuation-local-storage").getNamespace;
let namespace = getNamespace("com.domain");
let data = namespace.get("data");
console.log("data : ", data);
于 2017-11-30T12:05:19.320 回答
0

不,它不会与所有请求一起共享,它只会在该请​​求中持续很长时间。

于 2020-03-26T12:37:22.910 回答