Так вот обзор архитектуры моей установки:Узел/Экспресс - запрос POST, чтобы получить почтовый с удаленного сервера, передать обратно клиенту
- PEBKAC
- AngularJS Frontend
- NodeJS/Экспресс Посредник
- Spring/Hibernate API
- MySQL Database
Прямо сейчас в Spring API у меня есть вызов API для динамического создания zip-файла. Этот вызов возвращает двоичный поток.
Что мне нужно сделать, это поймать этот поток в узле/экспресс и передать его обратно в интерфейс AngularJS.
Поездка пользователя заключается в том, что пользователь проверяет список экспортируемых товаров, нажимает кнопку для подтверждения экспорта, а HTTP-запрос делается на узел. Затем узел отправляет запрос Spring, который возвращает поток, и отправляет результат обратно в AngularJs.
Не нужно никаких лекций о том, как мы не должны иметь Node/Express или Spring - архитектура изменится, и сейчас это много устаревшего кода.
Текущий Экспресс запрос на Spring:
exports.zipRequest = function(path, postBody, onResult) {
var options = {
host: host,
port: port,
path: springContext + path,
method: 'POST',
encoding: 'binary',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/zip'
}
};
var req = http.request(options, function (res){
var output = '';
res.setEncoding('binary');
res.on('data', function (chunk) {
output += chunk;
});
res.on('end', function() {
onResult(res.statusCode, output);
});
}).on('error', function(e) {
console.log("Got error: " + e.message);
req.end();
});
req.write(postBody.toString());
req.end();
};
Текущий узел API:
exports.exportSessions = function(req, res) {
var dataset = req.user.dataset;
var id = req.params.id;
var arr = JSON.stringify(req.body);
var today = new Date();
var filename = today.toISOString();
filename = filename.replaceAll("-","_");
filename = filename.replaceAll(":","_");
filename = filename.replace(".","_");
var path = '/Export/dataset/'+dataset+'/exportZip/';
api.zipRequest(path, arr, function(statusCode, result) {
if(statusCode != 200) {
console.log(statusCode);
console.log(result);
res.send(statusCode, "Problem from backend API");
} else {
if (result != null || typeof result != 'undefined') {
res.type('application/zip')
res.attachment(filename+'.zip');
res.send(result, 'binary');
} else {
res.send(statusCode, "Undefined Result" + result);
}
}
});
};
Глядя, чтобы выяснить, как получить браузер клиента, чтобы сохранить возвращаемый файл - как я могу видеть двоичный string fine, и я устанавливаю все необходимые заголовки. Я пробовал все от создания буфера в выражении и возвращаю его в res.write()
в ответе API узла и ничего не работает.
EDIT:
Так что мне удалось получить Экспресс Pipe почтовый обратно клиенту в полном объеме, используя следующие:
var req = http.request(options, function (res){
var today = new Date();
var filename = today.toISOString();
filename = filename.replaceAll("-","_");
filename = filename.replaceAll(":","_");
filename = filename.replace(".","_");
res.setEncoding('binary');
res.pipe(onResult);
};
и в узле:
exports.exportSessions = function(req, res) {
var dataset = req.user.dataset;
var id = req.params.id;
var arr = JSON.stringify(req.body);
var today = new Date();
var filename = today.toISOString();
filename = filename.replaceAll("-","_");
filename = filename.replaceAll(":","_");
filename = filename.replace(".","_");
var path = '/Export/dataset/'+dataset+'/exportZip/';
res.type('application/zip')
res.attachment(filename+'.zip');
return api.zipRequest(path, arr, res);
}
Я вижу в консоли разработчика, что все потоки файлов для клиента (браузера) и заголовки ответов следующие:
access-control-allow-headers:Origin, Content-Type, X-Auth-Token
access-control-allow-methods:POST, GET
access-control-allow-origin:*
cache-control:private, no-cache, must-revalidate
Connection:keep-alive
content-disposition:attachment; filename="2016_11_16T09_34_50_976Z.zip"
content-type:application/zip
Date:Wed, 16 Nov 2016 09:34:51 GMT
expires:-1
Transfer-Encoding:chunked
X-Powered-By:Express
По-прежнему нет кубиков при получении приглашения на сохранение.