每个HTTP /会话请求的GLOBAL数据?

题:

有没有办法在每个会话/ http请求中创build一个variables存储? 该variables必须是全局可访问的,并且不同的每个HTTP请求/连接/会话,并且不需要从function传递到function。

例如(只是为了说明):

setVariableThatCanBeAccessedByThisHTTPRequestOnly( 'a string data' ); 

任何东西都应该可以工作,但我宁愿远离将它从function传递到function。

 //I'm trying to get rid of passing req parameter to all custom functions. //I'd like to store it in a variable somehow, that it can be accessed globally, but only within that session/request. exports.functionName = function( req, res ) { customFunctionThatRequiresReq( req ); }; 

原始问题

最近我一直在玩node.js,并对它的GLOBAL范围有点担心。 假设我们有一个server.js文件:

 username = ""; //Global scope 

然后,当build立连接并且服务器收到请求时,它将执行以下操作:

 username = selectUsernameWithConditions(); //This will return a username 

我的问题是:如果两台不同的计算机向服务器发送请求,那么username的值是否会独立不同呢? 我的意思是,当处理第一个请求的时候username和第二个请求处理时的username是不同的,还是只是一个variables,会被覆盖?

如果它们被覆盖,那么只有在请求和/或会话中存储数据并使其全局可访问的最好方法是什么? 例如,下面的代码:

 username = selectUsernameWithConditions(); //This will return a username 

将为不同的请求分配不同的username ,而不是覆盖对方。

是的,有一些注意事项。 您正在寻找一个名为continuation-local-storage的模块。
这使您可以为当前请求的其余callback保留任意数据,并以全局方式访问它。
我在这里写了一篇关于它的博客文章。 但要点是:

  1. 安装cls: npm install --save continuation-local-storage
  2. 为您的应用程序创build一个名称空间(位于应用程序主文件的顶部)

     var createNamespace = require('continuation-local-storage').createNamespace, namespace = createNamespace('myAppNamespace'); 
  3. 创build一个在cls(continuation-local-storage)命名空间中运行下游函数的中间件

     var getNamespace = require('continuation-local-storage').getNamespace, namespace = getNamespace('myAppNamespace'), app.use(function(req, res, next) { // 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() { namespace.set('foo', 'a string data'); next(); }); }); 
  4. 由于您在namespace.run运行了next ,因此任何下游函数都可以访问命名空间中的数据

     var getNamespace = require('continuation-local-storage').getNamespace, namespace = getNamespace('myAppNamespace'); // Some downstream function that doesn't have access to req... function doSomething() { var myData = namespace.get('foo'); // myData will be 'a string data' } 
  5. 有一点需要注意的是某些模块可以“丢失”由cls创build的上下文。 这意味着当你去命名空间查找'foo'时,它不会有。 有几种方法可以解决这个问题,即使用另一个模块,如cls-redis ,cls-q或绑定到命名空间。

您可以使用不稳定的function:nodejs 域

我这样做是为了让我阅读文档,并弄清楚它是如何工作的;)

在层次结构中创build一个中间件,它将创build一个域并在该域的上下文中运行剩余的请求处理程序:

 app.use(function(req, res, next) { var domain = domain.create(); domain.req = req; domain.run(next); }); 

然后在您的处理程序中的任何地方,可以通过以下方式访问当前请求

 var req = process.domain.req; 

再次,阅读文档,我真的不知道这一切,但这是一种方法!

根据要求,我想你以后可以用普通的closures来完成。 例如,你可以在需要req参数的模块中定义自定义函数:

util_funcs.js:

 module.exports = function( req ){ return { customFunctionThatRequiresReq: function(){ console.info( req ) }, otherFunctionThatRequiresReq: function(){ console.log( req ) } }; }; 

然后,无论您依赖于这些function(大概是应用程序中的其他某个中间件),您只需要在上下文中提供它们:

 var someMiddleWare = function( req, res, next ){ var utils = require( 'util_funcs.js' )( req ); utils.customFunctionThatRequiresReq(); utils.otherFunctionThatRequiresReq(); }; 

这可以让你避免乱扔你的函数参数req ,而不是可疑的全局variables。

如果我是正确的了解你的问题,你可以尝试使节点js中可以存储用户名的全局variables

你可以使用具有唯一ID的全局数组

假设user1命中http请求,因此你在js节点中这样存储

 if(!username) username = []; if(!uniqId) uniqId = 0; uniqId++; username[uniqId] = 'xyz'; 

类似这样的工作

你有没有尝试使用cookies? 将cookie设置为浏览器,然后每次有请求时,您都可以通过cookie了解用户。您可以使用“cookie-parser”节点库。