我已经在nodejs中设置了一个代理服务器,该代理服务器进入我们的一个后端服务器以获取数据;一些数据(例如会话ID)存储为cookie。我想要做的是让代理获取远程cookie,然后推送到原始请求的响应头,然后发回响应。我关闭了,但遇到了障碍:
app.get(/\/json\/(.+)/, getJson);
var getJson = function(req, response1) {
response1.setHeader('Content-Type', 'application/json; charset=utf-8');
var before1stWrite = true;
utils.setCookies(response1, ["floo=flum"]) // this works
var options = {
host : config.scraperUrl.replace('http://', ''),
path : '/rwd/' + req.params[0] + '?' + querystring.stringify(req.query),
method : "GET",
rejectUnauthorized : false
};
var request = https.request(options, function(response2) {
response2.setEncoding('utf8');
// utils.setCookies(response1, ["flib=flah"]) // this fails, too
response2.on('data', function(d) {
if (before1stWrite) {
console.log(response2.headers['set-cookie']); // remote's cookies
utils.setCookies(response1, ["flib=flah"]) // this fails
before1stWrite = false;
}
response1.write(d);
});
response2.on('end', function() {
response1.end()
});
});
request.end();
request.on('error', function(e) {
console.error("error occurred: " + e.message);
response1.end();
});
}
setCookies(response1,cookies)只是通过cookie循环而已 res.setHeader(' Set-Cookie',cookie)
问题是,在调用第二个setCookies时,看起来标题已经被烘焙了;将方法移动到数据'事件处理程序没有帮助。我得到的错误是:
http.js:689
throw new Error('Can\'t set headers after they are sent.');
是否有任何方法可以向response2添加我从response2收到的标题?
更新
我修复了代码,以确保在任何其他写入之前尝试写入response1的头文件;然而,这不是一个解决办法。
答案 0 :(得分:1)
是的,您无法在数据开始流动后发送标头。您是否尝试在此行后设置标题?
response.setEncoding('utf8');
另外,您是否考虑使用流而不是大块传输? http://nodejs.org/api/stream.html
答案 1 :(得分:1)
您需要缓冲数据。 这样做非常像管道:
response.on('data', function(d) {
res.write(d);
});
所以你马上发送回复。没试过,但这应该有效:
var data = "";
response.on('data', function(d) {
data += d;
});
response.on('end', function() {
console.log(response.headersSent);
console.log(response.headers['set-cookie']);
utils.setCookies(res, ["flib=flah"])
res.write(data);
res.end();
});
请记住,您正在将所有数据缓冲到内存中,不建议用于大型响应。