每个HTTP/会话请求的全局数据
GLOBAL data per HTTP/Session request?
问题:
是否有任何方法可以在每个会话/http请求中创建变量存储?变量必须是全局可访问的,并且每个HTTP请求/连接/会话都不同,并且不需要在函数之间传递
例如(只是举例说明(:
setVariableThatCanBeAccessedByThisHTTPRequestOnly( 'a string data' );
任何东西都应该起作用,但我更愿意避免在函数之间传递它。
//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
然后,当建立连接并且服务器收到请求时,它将执行以下操作:
username = selectUsernameWithConditions(); //This will return a username
我的问题是:如果两台不同的计算机向服务器发送请求,那么username
的值会独立不同吗?我的意思是,第一个请求处理时的username
与第二个请求处理后的username
不同,还是它们只是一个变量,将被覆盖?
如果它们被覆盖,存储数据并使其仅在该请求和/或会话中全局可访问的最佳方式是什么?例如,以下代码:
username = selectUsernameWithConditions(); //This will return a username
将为不同的请求以不同的方式分配username
,并且不会相互覆盖。
是的,有一些注意事项。您正在寻找一个称为延续本地存储的模块
这允许您为当前请求的剩余回调保留任意数据,并以全局方式访问它
我在这里写了一篇关于它的博客文章。但要点是:
- 安装cls:
npm install --save continuation-local-storage
-
为您的应用程序创建一个命名空间(位于应用程序主文件的顶部(
var createNamespace = require('continuation-local-storage').createNamespace, namespace = createNamespace('myAppNamespace');
-
创建一个在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(); }); });
-
由于您在
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' }
-
需要注意的是,某些模块可能会"丢失"cls创建的上下文。这意味着当你在命名空间上查找"foo"时,它不会有它。有几种方法可以解决这个问题,即使用另一个模块,如cls-redis、cls-q或绑定到命名空间。
根据请求,我认为您所追求的可以用普通闭包来完成。例如,您可以在采用req
参数的模块中定义自定义函数:
util_funcs.js:
module.exports = function( req ){
return {
customFunctionThatRequiresReq: function(){ console.info( req ) },
otherFunctionThatRequiresReq: function(){ console.log( req ) }
};
};
然后,无论您在哪里依赖这些功能(可能是应用程序中其他地方的一些中间件(,您都可以在上下文中要求它们:
var someMiddleWare = function( req, res, next ){
var utils = require( 'util_funcs.js' )( req );
utils.customFunctionThatRequiresReq();
utils.otherFunctionThatRequiresReq();
};
这使您可以避免在函数args中乱丢req
,并且没有可疑的全局变量。
如果我理解你的问题是正确的,你可以尝试在节点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;
再次阅读文档,我真的不确定这一切,但这是一种方法!
您尝试过使用cookie吗?将cookie设置为浏览器,然后每次有请求时,你就会通过cookie来了解用户。。您可以使用"cookie解析器"节点库。
- 如何使用Mongoose将数据传递到全局变量
- 将 Ajax 数据分配给全局变量时出现问题
- 如何在jquery中将xml解析数据获取为全局变量
- Angular promise服务作为全局数据服务
- 数据不充当服务的全局表单工厂
- AngularJS ui-router:如何全局解析所有路由的典型数据
- 我需要做什么才能访问控制器中的全局数据
- 将输入数据保存到全局变量
- 加载外部数据并使其保持全局JavaScript
- 如何在Meteor Iron路由器的内部模板中访问全局数据
- NodeJS与AngularJS,所需的HTML文件不是跨控制器的数据绑定全局变量
- 节点模块包括数据文件作为全局变量
- 角度 JS 数据绑定 - 全局数据
- Javascript存储/全局数据/对象的状态
- Polymer应用程序的全局数据存储
- 带有react路由器的全局数据
- 每个HTTP/会话请求的全局数据
- 在angular JS中存储全局数据的地方
- Vue.js -来自AJAX调用的全局数据
- 存储某些页面的全局数据的最佳方式