在使用LoopbackJS的Node.js项目构建中,我需要在请求期间存储数据。
所以我使用了domain功能:
// 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的请求按预期工作。有什么建议吗?
错误回复:
{"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)"}}
答案 0 :(得分:2)
刚刚发现,在创建时,explisity绑定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()
});
});
不知道为什么会这样,所以我提出其他可能的建议。
答案 1 :(得分:1)
值得一提的是域are not meant to be used to handle errors in this manner。相反,域意味着用于允许整个应用程序的模块安全崩溃(例如,您可能希望在沙箱中运行第三方代码)。这里不需要域名(当然,你可以自由使用域名)
此外,仅在给定函数从域堆栈内执行时才设置process.domain
。您不提供有关Model的调用站点的信息,因此我只能假设您的模型是从此堆栈外部调用的,这会导致错误。
鉴于您正在挂钩beforeRemote
,执行远程操作之前执行,我将假设从域堆栈外部调用,并且因此process.domain
未定义是预期的行为。
答案 2 :(得分:1)
对于此问题的读者来说,了解Node's Domain module已被弃用且不应使用,这一点非常重要。
如果你来这里寻找这个问题的解决方案,那么你最好不要寻找域模块以外的东西。
此模块正在等待弃用。更新API完成后,将完全弃用此模块。大多数最终用户不应该有使用此模块的原因。绝对必须具有域提供的功能的用户可能暂时依赖它,但是应该期望将来必须迁移到不同的解决方案。
虽然这在技术上并没有回答OP的问题,但我相信它是正确的解决方案"对于这个问题的大多数读者。
使用Domain的替代方法是continuation-local-storage模块。