如何解码节点js中的分块数据?

时间:2017-07-20 02:46:43

标签: node.js http

我从节点服务器接收PDF文件(它在此服务器上运行jsreport),我需要在客户端下载此PDF(我在客户端使用反应)但问题是当我下载时文件,它全部空白,标题有些奇怪的符号。经过大量的测试和研究后,我发现问题可能是文件被嵌入(我可以在响应的标题中看到)并且我需要解码才能再次成为文件。

那么,如何将这个分块的字符串再次解码为文件?

在客户端我只是下载响应中的文件:

handleGerarRelatorioButtonClick(){
    axios.post(`${REQUEST_URL}/relatorios`, this.state.selectedExam).then((response) => {
      fileDownload(response.data, this.state.selectedExam.cliente.nome.replace(' ', '_') + ".pdf");
    });
  }

在我的服务器中,我正在向其他节点服务器的jsreport发出请求,并以PDF格式返回报告:

app.post('/relatorios', (request, response) => {
      var exame = new Exame(request.body);
      var pdf = '';
      var body = {
        "template": {
          "shortid": "S1C9birB-",
          "data": exame
        }
      };

      var options = {
        hostname: 'localhost',
        port: 5488,
        path: '/api/report',
        method: 'POST',
        headers: {
          'Content-Type': 'application/json'
        }
      };
      var bodyparts = [];
      var bodylength = 0;
      var post = http.request(options, (res) => {
        res.on('data', (chunk) => {
          bodyparts.push(chunk);
          bodylength += chunk.length;
        });

        res.on('end', () => {
          var pdf = new Buffer(bodylength);
          var pdfPos = 0;
          for(var i=0;i<bodyparts.length;i++){
            bodyparts[i].copy(pdf, pdfPos, 0, bodyparts[i].length);
            pdfPos += bodyparts[i].length;
          }
          response.setHeader('Content-Type', 'application/pdf');
          response.setHeader('Content-disposition', exame._id + '.pdf');
          response.setHeader('Content-Length', bodylength);
          response.end(Buffer.from(pdf));
        });
      });

      post.write(JSON.stringify(body));
      post.end();
   });

我确信我的报告正在按预期呈现,因为如果我向邮递员提出请求,它会返回PDF就好了。

1 个答案:

答案 0 :(得分:0)

您的解决方案只是简单地传递数据块,但您并没有告诉您的前端对这些块有什么期望或如何组装它们。至少应该将Content-Type响应标头设置为application/pdf,并且要完成,还应该发送Content-disposition以及Content-Length。您可能需要从第三方源收集PDF到缓冲区,然后如果您无法设置标题和管道以成功响应,则将该缓冲区发送到您的客户端。

[edit] - 我不熟悉jsreport,但是他们发送的响应可能(并且可能)是缓冲区。如果是这种情况,您可以使用类似的东西代替您对客户的回复:

myGetPDFFunction(params, (err, res) => {
  if (err) {
    //handle it
  } else {
    response.writeHead(200, {
      'Content-Type': 'application/pdf',
      'Content-Length': [your buffer's content length]
    });
    response.end(Buffer.from([the res PDF buffer]));
  }
}

您尚未显示的是获取该PDF的请求,因此我目前无法提供更具体的信息。您应该查看jsreport的文档以查看它在响应中发送的内容,并且您还可以阅读缓冲区here

这是粗略的伪代码,但重点是在将标头设置为正确的值后使用PDF缓冲区进行响应。