Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/40.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 每个HTTP/会话请求的全局数据?_Javascript_Node.js_Express_Request_Global - Fatal编程技术网

Javascript 每个HTTP/会话请求的全局数据?

Javascript 每个HTTP/会话请求的全局数据?,javascript,node.js,express,request,global,Javascript,Node.js,Express,Request,Global,问题: 有没有办法在每个会话/http请求中创建变量存储?变量必须是全局可访问的,并且每个HTTP请求/连接/会话都不同,并且不需要在函数之间传递。 例如(仅举例说明): 任何东西都应该可以工作,但我不想把它从一个函数传递到另一个函数 //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

问题:

有没有办法在每个会话/http请求中创建变量存储?变量必须是全局可访问的,并且每个HTTP请求/连接/会话都不同,并且不需要在函数之间传递。

例如(仅举例说明):

任何东西都应该可以工作,但我不想把它从一个函数传递到另一个函数

//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,有点担心它的全局范围。假设我们有一个server.js文件:

username = ""; //Global scope
然后,当建立连接且服务器收到请求时,它将执行以下操作:

username = selectUsernameWithConditions(); //This will return a username
我的问题是:如果两台不同的计算机向服务器发送请求,
username
的值是否会独立不同?我的意思是,处理第一个请求时的
用户名
是否与处理第二个请求时的
用户名
不同,或者它们只是一个变量,将被覆盖

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

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

将为不同的请求分配不同的
用户名
,并且不会相互覆盖。

如果我正确理解您的问题,您可以尝试在节点js中创建全局变量,该变量可以存储用户名

您可以使用具有唯一id的全局数组

假设user1点击http请求,因此在节点js中存储如下内容

if(!username)
   username = [];

if(!uniqId)
   uniqId = 0;
uniqId++;

username[uniqId] = 'xyz';

与此类似,它正在工作

您可以使用一个不稳定的功能:nodejs

我是在脑子里想的,所以请阅读文档,了解它是如何工作的;)

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

app.use(function(req, res, next) {
  var domain = domain.create();
  domain.req = req;
  domain.run(next);
});
然后,在处理程序中的任何位置,您都可以通过以下方式访问当前请求:

var req = process.domain.req;
再次,阅读文档,我真的不确定所有这些,但这是一种方法

是的,有一些警告。 您正在寻找一个名为的模块。
这允许您为当前请求的其余回调保留任意数据,并以全局方式访问它。
我写了一篇关于它的博客文章。但要点是:

  • 安装cls:
    npm安装--保存本地存储
  • 为应用程序创建命名空间(在应用程序主文件的顶部)

  • 创建在cls(延续本地存储)命名空间中运行下游函数的中间件

    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();
      });
    });
    
    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'
    }
    
  • 由于您在
    名称空间中运行了
    next
    。run
    ,因此任何下游函数都可以访问名称空间中的数据

    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();
      });
    });
    
    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'
    }
    
  • 需要注意的是,某些模块可能“丢失”cls创建的上下文。这意味着,当您在名称空间上查找'foo'时,它将不会有它。有几种方法可以解决这个问题,即使用另一个模块,如cls-q或绑定到名称空间


  • 根据请求,我认为您需要的是普通闭包。例如,您可以在采用
    req
    参数的模块中定义自定义函数:

    util_funcs.js:

    然后,无论您在哪里依赖这些功能(可能是应用程序中其他地方的某个中间件),您都可以在上下文中需要它们:

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

    这使您可以避免在函数参数中乱扔
    req
    ,并且没有可疑的全局变量。

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

    可能
    var usernames={};usernames[requestID]=选择usernamewithconditions()
    然后您可以获取与特定请求关联的用户名。嗨,RobG。这实际上是个好主意。但是,作为
    requestID
    使用的变量是什么?如果两个不同的请求/会话之间存在相同的情况,这将是一件痛苦的事情。可以将其附加到请求中,例如
    req.username=selectUsernameWithConditions()
    ?Hi candu。如果我将它附加到请求,我可以在处理请求的函数之外访问它吗?例如:
    exports.index=function(req,res){/*我的函数必须在这个范围内才能访问req*/}
    @cuzmAZN:如果您想访问
    username
    ,您必须将
    req
    (或仅是
    username
    )传递给从路由处理程序中调用的任何函数。您好!谢谢你的回答。我已经想到了这一点,但问题是如何知道HTTP请求使用的是哪个uniqueID?你必须有一个变量告诉服务器它是哪一个ID,这又是同一个故事,我们必须传递这个唯一ID.:-/。是否应该存在每个请求都是唯一的内置会话ID?您的节点js脚本是否可以连续运行,例如processHi。这可能是我见过的最接近的答案。但它不稳定。但我确实从这个答案中学到了很多。让我花几天时间看看还有什么问题。很好,但在一些请求中,域没有时间初始化。这是最接近我要找的,尽管有点复杂!非常感谢你的启示!如果您遇到任何麻烦或有任何问题,请告诉我。这是最前沿的节点,我有一个帖子在几天后出来讨论它。也就是说,现在在生产中使用它是安全的。老实说,这是最好的答案。如此优雅。这正是医生要的。非常感谢。如果你正在给出答案,用一个小例子来解释;否则,将其作为评论写下来。
    var someMiddleWare = function( req, res, next ){
    
      var utils = require( 'util_funcs.js' )( req );
    
      utils.customFunctionThatRequiresReq();
      utils.otherFunctionThatRequiresReq();
    
    };