在发出POST请求时返回空白PDF但在GET中正常工作

时间:2015-01-25 23:24:27

标签: angularjs node.js express wkhtmltopdf angularjs-http

我有一个AngularJs前端和一个NodeJS后端。我正在尝试基于AngularJS中的一些参数在NodeJS上构建PDF并返回PDF作为响应。

当我从AngularJS发出GET请求时,我正在使用的代码似乎正常工作,但是当我发出POST请求时它返回一个空白的PDF。我需要发一个POST请求,因为我必须发送一些特定的数据。

我首先将文件保存在磁盘上,然后将其发送到前端,以便我可以看到正确生成PDF。它未正确发送或在FrontEnd上正确读取。

以下是我的AngularJS代码

var url = {{My Node Server URL}};
            (Note: Works when I make a Get request, without sending post params)
            var $promise = $http.post(encodeURI(url), {
                    responseType: 'arraybuffer',
                    competitors: competitors,
                    channels: channels
            });

            $promise.then(

                function success(response) {


                    var blob = new Blob([response.data], { type : 'application/pdf' });
                    var pdfLink = (window.URL || window.webkitURL).createObjectURL( blob );

                    window.open(
                      pdfLink,
                      '_blank' // <- This is what makes it open in a new window.
                    );

                    cb(pdfLink);

              }, function error(response) {

                --Error Handling--
              }
           )

以下是我的NodeJS代码

wkhtmltopdf(
            html,
            { 
                output: pdfName
            },
            function (code, signal) {
                fs.readFile(pdfName, function (err, data) {
                    if (err) {res.writeHead(400); res.end("" + err); return;}

                    res.writeHead(
                        200,
                        {
                            "content-type" : "application/pdf",
                            "Content-Disposition": "attachment; filename=Best.pdf "
                        }
                    );
                    res.end(data);
                });     
            }
        );

我已经调查了很多地方,并尝试了几乎所有的东西,但似乎没有任何工作。任何提示/帮助/建议将不胜感激。请问我是否需要提供更多信息或细节。 TIA

2 个答案:

答案 0 :(得分:8)

知道了!我只需将responseType作为arraybuffer添加为另一个参数。我认为这是为什么这有效的自我解释。 所以下面的代码工作了!

var $promise = $http.post(encodeURI(url), {
                    competitors: competitors,
                    channels: channels
            },{responseType: 'arraybuffer'});

答案 1 :(得分:2)

对于使用Angular 2+的此方案有问题的人,解决方案是相同的,但执行方式不同。请参阅:https://angular.io/docs/ts/latest/api/http/index/ResponseContentType-enum.html

在我的应用程序中,我将一个doc名称传递给我的express服务器,该服务器使用res.download(filename)传回文件。

前端服务如下:

downloadDoc(docName: string) {
  let pkg = {docName: docName};
  let opts = new RequestOptions({
    responseType: ResponseContentType.ArrayBuffer
  });
  return this.http
          .post(this.baseUrl + '/downloadDoc', pkg, opts)
          .toPromise()
          .then((res: any) => {
            let blob = new Blob([res._body], {type: 'application/pdf'});
            return blob;
          });
}