我有一个在一个VM1上运行的REST API服务器。在其他VM2机器上,我构建了一个作为代理运行的节点js服务器。在同一台VM2机器上我有应用程序(托管apache,只提供html,js和css文件)。我的节点js服务器只将api调用重新发送回API服务器。这工作正常,直到新要求到来 - 添加新的API端点(在节点js服务器上)下载文件(csv)。为了使下载发生,我需要使用GET方法。问题是所需的数据仅在主API服务器的POST端点上可用,我正在调用API端点来获取数据并将其发回。这是我试图解决的代码:
var express = require('express');
var cors = require('cors');
var request = require('request');
var http = require('http');
var csv = require("fast-csv");
var config = require("./config.js");
var corsOptions = {
origin: function(origin, callback){
var originIsWhitelisted = config.whitelist.indexOf(origin) !== -1;
callback(null, originIsWhitelisted);
}
};
var handler = function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello World\n');
};
var app = express();
// Enable CORS for all requests
app.use(cors(corsOptions));
app.options('*', cors(corsOptions)); // specially for pre-flight requests
app.get('/download', function(req, res){
var limit = req.query.limit;
var offset = req.query.offset;
var options = {
method: 'POST',
url: config.apiServerHost + '/search',
useQuerystring: true,
qs: {'limit': limit, 'offset': offset},
rejectUnauthorized: false,
body: 'from=date&to=date'
};
var filename = 'data.csv';
res.setHeader('Content-disposition', 'attachment; filename=\"data.csv\"');
res.setHeader('content-type', 'text/csv');
var csvStream = csv.createWriteStream({
headers: true,
objectMode: true,
transform: function (row) {
return row;
}
});
console.log(options);
function callback(error, response, body) {
if (!error && response.statusCode == 200) {
var data = JSON.parse(body);
for(var i = 0; i < data.length; i++)
csvStream.write({
"col1": "value1-"+data[0][i],
"col2": "value2-"+data[1][i],
"col3": "value3-"+data[2][i],
"col4": "value4-"+data[3][i]
});
}
csvStream.end();
}
else {
console.log("Error:", error, body);
}
}
req.pipe(request(options, callback));//.pipe(res)
csvStream.pipe(res);
});
app.use('/api', function(req, res) {
var url = config.apiServerHost + req.url;
console.log(url);
req.pipe(request({
"rejectUnauthorized": false,
"url": url
}, function(error, response, body){
if(error) {
console.log(new Date().toLocaleString(), error);
}
})).pipe(res);
});
当请求方法是POST(与主API服务器相同)时,所有代码都可以正常工作。但是,当我在options
对象中添加正文时,我会收到&#34; [错误:写完后]&#34; 。有人可以帮我弄清楚发生了什么以及如何解决这个问题?感谢。
答案 0 :(得分:0)
[Error: write after end]
显示.end()
后的点数据,代码为
req.pipe(request(options, callback));//.pipe(res) csvStream.pipe(res);
在callback
函数中调用csvStream.end();
,然后调用csvStream.pipe
可能会导致此错误。