有时Node.js的process.domain是未定义的

在Node.js项目中使用LoopbackJS构build我需要在请求期间存储数据。

所以我使用了域function:

// pre-processing middleware app.use(function (req, res, next) { // create per request domain instance var domain = require('domain').create(); // save request and response to domain, to make it accessible everywhere domain.req = req; domain.res = res; domain.run(next); }); 

后来在需要的模块中:

 Model.beforeRemote('**', function(oContext, oModel, next) { // Save method name for later use process.domain.remoteContext = { /* Here is an error thrown */ methodName: oContext.method.name }; ... process.domain.res.send() // example of usage }) 

但是当我从Safari或IE请求时,process.domain有时是不确定的! 从Chrome或Firefox请求按预期工作。 有什么build议么?

错误回应:

 {"error":{"name":"TypeError","status":500,"message":"Cannot set property 'remoteContext' of undefined","stack":"TypeError: Cannot set property 'remoteContext' of undefined\n at module.exports (/Users/igormatyushkin/projects/Yash/server/hooks/admin-remote.js:12:34)\n at Function.Model.setup.ModelCtor.beforeRemote.args (/Users/igormatyushkin/projects/Yash/node_modules/loopback/lib/model.js:184:9)\n at execStack (/Users/igormatyushkin/projects/Yash/node_modules/loopback/node_modules/strong-remoting/lib/remote-objects.js:363:13)\n at RemoteObjects.execHooks (/Users/igormatyushkin/projects/Yash/node_modules/loopback/node_modules/strong-remoting/lib/remote-objects.js:372:10)\n at RemoteObjects.invokeMethodInContext (/Users/igormatyushkin/projects/Yash/node_modules/loopback/node_modules/strong-remoting/lib/remote-objects.js:512:8)\n at async.series.results (/Users/igormatyushkin/projects/Yash/node_modules/loopback/node_modules/strong-remoting/node_modules/async/lib/async.js:610:21)\n at _asyncMap (/Users/igormatyushkin/projects/Yash/node_modules/loopback/node_modules/strong-remoting/node_modules/async/lib/async.js:249:17)\n at async.eachSeries.iterate (/Users/igormatyushkin/projects/Yash/node_modules/loopback/node_modules/strong-remoting/node_modules/async/lib/async.js:149:13)\n at async.eachSeries (/Users/igormatyushkin/projects/Yash/node_modules/loopback/node_modules/strong-remoting/node_modules/async/lib/async.js:165:9)\n at _asyncMap (/Users/igormatyushkin/projects/Yash/node_modules/loopback/node_modules/strong-remoting/node_modules/async/lib/async.js:248:13)"}} 

刚刚发现,在创build时显式绑定req和res到域,解决了在执行堆栈中未定义的域。

 app.use(function (req, res, next) { // create per request domain instance domain.create().run(function() { // explicit binding process.domain.add(req) process.domain.add(res) // save request to domain, to make it accessible everywhere process.domain.req = req; process.domain.res = res; next() }); }); 

不知道为什么发生这种情况,所以我留下了其他可能的build议的问题。

值得一提的是,域名并不是用来处理这种错误的 。 相反,域名是用来允许整个应用程序的模块安全地崩溃(例如,也许你想在沙箱中运行第三方代码)。 这里没有必要使用域名(尽pipe你当然可以自由使用域名)

此外,只有在给定函数从域堆栈中执行的情况下,才会设置process.domain 。 您不提供有关Model的调用站点的信息,所以我只能假定您的模型正在从该堆栈的外部被调用,这是导致错误的原因。

假设你正在执行远程动作执行之前执行的beforeRemote ,我将假定从域堆栈外被调用,因此process.domain是未定义的行为。

对于这个问题的读者来说,了解Node的域模块已经被弃用,不应该被使用,这一点很重要。

如果你来这里寻找解决这个问题的方法,那么你最好是寻找除了域模块之外的东西。

此模块正在等待弃用。 一旦更换API已经完成,这个模块将被完全弃用。 大多数最终用户不应该有理由使用这个模块。 绝对必须具有域提供的function的用户可能暂时依赖它,但是应该期望在将来不得不迁移到不同的解决scheme。

虽然这在技术上没有回答OP的问题,但我相信这是这个问题的大多数读者的正确的“解决scheme”。

continuation-local-storage模块是使用Domain的替代方法。