Пустой PDF-файл возвращается при выполнении запроса POST, но отлично работает с GET

У меня есть интерфейс AngularJs и серверная часть NodeJS. Я пытаюсь создать PDF-файл на NodeJS на основе некоторых параметров из AngularJS и вернуть PDF-файл в ответ.

Код, который я использую, работает нормально, когда я делаю запрос GET из AngularJS, но возвращает пустой PDF-файл, когда я делаю запрос POST. Мне нужно сделать запрос 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);
                });     
            }
        );

Я заглянул во многие места и перепробовал почти все, но ничего не работает. Любой намек/помощь/предложение будут оценены. Пожалуйста, спросите, нужно ли мне предоставить дополнительную информацию или детали. ТИА


person Sambhav Sharma    schedule 25.01.2015    source источник
comment
Вам нужно опубликовать код, который извлекает параметры из запроса в вашей структуре. Вероятно, вы не получаете его так же, как в запросе на получение.   -  person Peter Ashwell    schedule 26.01.2015
comment
Нет, это не имеет ничего общего с параметрами. Я могу получить параметры из обоих запросов. Как я уже сказал, PDF-файл создается нормально в обоих случаях. Могу проверить на сервере. Разница в том, что он отображается пустым во внешнем интерфейсе, когда я использую запрос POST. Я знаю, что это действительно странно! :( Большое спасибо, что нашли время.. И за просьбу разъяснений..   -  person Sambhav Sharma    schedule 26.01.2015


Ответы (2)


Понятно! Мне просто нужно было добавить responseType в качестве буфера массива в качестве еще одного аргумента. Я думаю, что это говорит само за себя, почему это сработало. Итак, следующий код сработал!

var $promise = $http.post(encodeURI(url), {
                    competitors: competitors,
                    channels: channels
            },{responseType: 'arraybuffer'});
person Sambhav Sharma    schedule 02.02.2015
comment
Спасибо Спасибо спасибо! На этом для меня закончилось несколько часов работы. Пока я не добавил {responseType: 'arraybuffer'} в свой вызов API, я все еще получал данные, я мог их сохранить, и Adobe Reader все еще открывал мой PDF-файл без ошибки. Эта проблема? PDF-файл был большего размера, чем исходный файл... и при отображении он был пустым. Как только я добавил свойство responseType, альт! Спасибо еще раз. - person Marcidius; 18.04.2016
comment
Для меня это не сработало, пока я не установил для responseType значение blob, а не arrayBuffer: stackoverflow.com/a/43041245/3093041< /а> - person ancab; 27.03.2017

Для тех, у кого есть проблемы с этим сценарием, использующим Angular 2+, решение такое же, но выполняется по-другому. См.: https://angular.io/docs/ts/latest/api/http/index/ResponseContentType-enum.html

В своем приложении я передал имя документа своему экспресс-серверу, который передает файл обратно с 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;
          });
}
person Daynil    schedule 16.04.2017