Node / Express – 从远程服务器接收邮编的POST请求,传回客户端

所以这里是我的设置的架构概述:

  • PEBKAC
  • AngularJS前端
  • NodeJS / Express Middleman
  • Spring / Hibernate API
  • MySQL数据库

现在在Spring API中,我有一个API调用来dynamic生成一个zip文件。 这个调用返回一个分块的二进制stream。

我需要做的是在Node / Express中捕获这个stream并将其传回到AngularJS前端。

用户旅程是用户勾选要导出的项目列表,点击button确认导出,并向Node发出http请求。 然后,节点向Spring发送请求,返回stream,并将结果返回给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罚款,我设置所有必要的标题。 我已经尝试了一切,从快速创build一个缓冲区,并返回到Node API响应res.write() ,似乎没有任何工作。

编辑:

所以我设法使用以下命令将Express to Pipe整个zip文件全部返回给客户端:

  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); } 

我可以在开发人员控制台中看到整个文件stream到客户端(浏览器),并且响应标头如下所示:

 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 

尽pipe如此,仍然没有骰子获得保存提示。

所以我终于明白了。 希望这会给任何想要提出初步要求的人提供一个相当深入的答案,然后从二级回复。

我通过使用npm 请求模块解决了这个问题,并且将我的Node API调用从POST修改为GET:

 var request = require('request'); exports.exportSessions = function(req, res, next) { var dataset = req.user.dataset; var arr = decodeURIComponent(req.query.ids); var path = '/Export/dataset/'+dataset+'/exportZip/'; console.log('Exporting Data '+arr); var options = { method: 'POST', uri: 'http://' + api.host + ':' + api.port + api.springContext + path, headers: { 'Content-Type': 'application/json', 'Accept': 'application/zip' }, json: true, body: JSON.parse(arr) }; request.post(options).pipe(res) } 

并改变我的Angular请求,只需打开一个新的窗口与获取url:

 $scope.exportData = function() { var ids = $scope.sessions.selected.map(function(ses){ return ses.id; }); var pars = encodeURIComponent(JSON.stringify(ids)); window.open('/api/sessions/export/sessions?ids='+pars+'&access_token='+Auth.getToken(), '_blank'); } 

这会使用NodeJS APIpath简单地打开一个新窗口,然后调用Spring / Hibernate API并将响应作为对原始请求的响应进行pipe理。

Node API的最后一行使用request向Spring / Hibernate服务器发出POST请求,并通过初始res对象传回响应。 希望这可以帮助其他人将远程二进制文件传回客户端。