避免传递请求对象
Avoid passing around request object
我正在编写一个使用共享 ('isomorphic') 代码库在客户端和服务器上呈现的 React 应用程序(Express 服务器)。在某些情况下,当服务器是渲染器时,我想访问请求对象,而不必到处传递它。由于节点一次响应一个请求,利用缓存变量并确保在发送响应之前重置它不是安全的吗?
这可行,但有人能告诉我为什么这是好主意还是坏主意吗?...
server.js
var r = require('./request-store');
app.use(function(req, res, next) {
r.set(req);
next();
});
var resolve = require('./resolve');
// ...deferring to react router for client / server routing
app.use(function(req, res) {
resolve().then(function(data) {
r.set(null);
res.render('index', { data: data });
});
});
请求-store.js
var r = null;
module.exports.set = function(req) { r = req; };
module.exports.get = function() { return r; };
resolve.js
var r = require('./request-store');
module.exports = function() {
return new Promise(resolve, reject) {
if (isServer) {
console.log(r.get());
resolve();
} else if (isClient) {
resolve();
}
}
};
但是如果您收到来自不同用户的两个同时请求会怎样?第一个请求将被缓存,第二个将覆盖第一个用户的请求。同时假设您正在执行一些 IO 并且需要在请求完成后访问该请求,那么第一个用户的请求对象将已经被第二个用户的请求覆盖。总的来说,这样做是非常危险的。最好的方法是使用某种内存键值存储,但您仍然需要以某种方式传递密钥。
鉴于 Node 是单线程的,并且您 看起来 没有执行任何 I/O,那么是的,您的代码对我来说看起来很安全。 Express 将 运行 所有中间件同步,因此到你的承诺 运行s(因为它也是同步的)r.get()
应该 return 正确的请求对象。
但是,我不确定您是否需要缓存它,您可以将它直接传递给 resolve
并使用闭包将其捕获到您的 promise
中
var resolve = require('./resolve');
// ...deferring to react router for client / server routing
app.use(function(req, res) {
// pass 'req' into `resolve`
resolve(req).then(function(data) {
r.set(null);
res.render('index', { data: data });
});
});
resolve.js
var r = require('./request-store');
module.exports = function(req) {
// capture 'req' for use later
return new Promise(resolve, reject) {
if (isServer) {
console.log(req);
resolve();
} else if (isClient) {
resolve();
}
}
};
我正在编写一个使用共享 ('isomorphic') 代码库在客户端和服务器上呈现的 React 应用程序(Express 服务器)。在某些情况下,当服务器是渲染器时,我想访问请求对象,而不必到处传递它。由于节点一次响应一个请求,利用缓存变量并确保在发送响应之前重置它不是安全的吗?
这可行,但有人能告诉我为什么这是好主意还是坏主意吗?...
server.js
var r = require('./request-store');
app.use(function(req, res, next) {
r.set(req);
next();
});
var resolve = require('./resolve');
// ...deferring to react router for client / server routing
app.use(function(req, res) {
resolve().then(function(data) {
r.set(null);
res.render('index', { data: data });
});
});
请求-store.js
var r = null;
module.exports.set = function(req) { r = req; };
module.exports.get = function() { return r; };
resolve.js
var r = require('./request-store');
module.exports = function() {
return new Promise(resolve, reject) {
if (isServer) {
console.log(r.get());
resolve();
} else if (isClient) {
resolve();
}
}
};
但是如果您收到来自不同用户的两个同时请求会怎样?第一个请求将被缓存,第二个将覆盖第一个用户的请求。同时假设您正在执行一些 IO 并且需要在请求完成后访问该请求,那么第一个用户的请求对象将已经被第二个用户的请求覆盖。总的来说,这样做是非常危险的。最好的方法是使用某种内存键值存储,但您仍然需要以某种方式传递密钥。
鉴于 Node 是单线程的,并且您 看起来 没有执行任何 I/O,那么是的,您的代码对我来说看起来很安全。 Express 将 运行 所有中间件同步,因此到你的承诺 运行s(因为它也是同步的)r.get()
应该 return 正确的请求对象。
但是,我不确定您是否需要缓存它,您可以将它直接传递给 resolve
并使用闭包将其捕获到您的 promise
var resolve = require('./resolve');
// ...deferring to react router for client / server routing
app.use(function(req, res) {
// pass 'req' into `resolve`
resolve(req).then(function(data) {
r.set(null);
res.render('index', { data: data });
});
});
resolve.js
var r = require('./request-store');
module.exports = function(req) {
// capture 'req' for use later
return new Promise(resolve, reject) {
if (isServer) {
console.log(req);
resolve();
} else if (isClient) {
resolve();
}
}
};