2

I could really use some help here, I have spent nearly three days on this.

Within my Node application I have an API call that uses https call to an external API to return a PDF which looks like the below code. (I understand I could call the external API from the frontend Angular code, however corporate rules prevent me from doing so)

%PDF-1.5
%������
1 0 obj
<<
/Author (XXXX)
/CreationDate (XXX)
/ModDate (XXXX)
/Creator (EXXXX)
/Title (XXXX)
/Producer (XXXX)
/Subject (XXXX)
>>
endobj
7 0 obj
<</Length 5273 /Filter /FlateDecode >>
stream
x��\�s[����?`��;�|�Cf:Z������i:Fz�y�H������=����w��HJv���3�>���b���=J)yA(�~~�.0��7������~]���_��f0-~2�S������$W���g�=�O�w�!�t3��e��`=fQ�Qc/��L�G�nrs#�U%��������������N+@F���G'L���������/�/�?GW��=�)�J�*
���
��9�����������    y08:}F���"g�o�'#rzN�N���)y��Y��v8���z��>���d@�=}z�+����������v~!N��P�z�@O<�Ov|�[F�v��w���3&(��    S��XLb������>!&$TN�r1�L�����*7j8�v���b��kZ�  ��1�M"�2�v �u��NJ���.��'�A��:
�
D ;,3%�d=��|�S ��;<<:�H������O���j�_�����G����!--�����W����x�"'����<��xQ�����iMVs�z1�irY����9���K2���/����^N�8n�5Z�O�^�g����$��xU_sU���dQ�4��`���Om�0��g5�/�s�|y9YM���4��:a=�Z�������G^O���&��2���B����k~�"o��]�_OV��|V�.�W����`.9�[[�hE����'��k���~f|{���PI��3T��*-����wqI.��'���+���EM86��8Z���=+��7�\'�L�1�?�/z���H��<�#�2��V�Mla\9[�x�2I4n�yE5�m�(��[q�z6���p�v�GC�t�uu��bZ�yv}���fy���`oJ�/��s(���b�_���3=�c���t��*����)DnK��y�bP,m(0�e�[0���2�t������y�<�tjq8�S���P��tP>"����)H�����8U�=qj����&��L���^�V,{=Zn�VU�z2�����Q���63caR!�wbm�\"Y�s{���H�,b����A'#���]�����<���(�(O/�8�_�������9�P��������68w?hB��]�q�J�2F�+[Kx�=F��4p�Q#�H�uZ�=�y~�����Pn�Z�C����*������_\��S�`��T���3Kot���Z�D��V�<BD;�S%�N��Q��`�����'e����������D���
��fGO�a�X[�{���2����gjOH��v�y4�(o������Lp����c�J�uc��=�)oK���QnTk7���M�=�:�P�N�2�m�[P��gG�6��mPghZ��Z�o�,C��H�J
��$&T���Y�3z?���W��e��O;��4�=���&���

.....(ALOT MORE)

%%EOF

-Node

var options = {
        host: config.fake.host,
        path: config.fake.apiUrl + pdfId,
        method: 'GET',
        rejectUnauthorized: false,
        headers: config.fake.headers
      };
      console.log(options);
      api.getCall(options, function (status, response) {
        res.status(status).send(response);
      });

Node then returns the PDF (in plain/text), which I am able to view the pdf data with the Chrome devtools. This is where im getting lost. I am trying convert the pdf data into a blob and then open the pdf in a new tab but when the new tab opens I get a dialog saying "Failed to load PDF document." The Angular code works if I hardcode a test pdf file and return it to the frontend, it does exactly what I need it too.

this._http.get(url, {responseType: 'blob'}).subscribe( data => {
    console.log(data);
    var file = new Blob([data], {type: 'application/pdf'});
    var fileURL = URL.createObjectURL(file);
    window.open(fileURL);
});

Unfortunately, I have exhausted all the google resources I could find and have tried alot more than just the above. I'd appreciate any input I could get on this. Thanks!

Schweit
  • 21
  • 1
  • 3
  • Can you hit the same api in POSTMAN or any other REST api browser? I doubt you are sending it in pdf. – Anshuman Jaiswal Mar 27 '18 at 04:17
  • I struggled to do the same thing in Angular, used [THIS](https://stackoverflow.com/questions/16086162/handle-file-download-from-ajax-post/23797348#23797348) workaround which does the same thing in using XHR. – Straw Hat Mar 27 '18 at 04:23
  • Have you tried changing your response header content type `Content-Type` to `application/pdf`? It might resolve the issue. – Behrooz Mar 27 '18 at 05:26
  • you can't directly send the file over the network. – Harshal Patil Mar 27 '18 at 05:43

1 Answers1

1

Node Response, You need to import fs library,

fs.stat(filepath, (err, stat) => {

    res.setHeader('Content-Length', stat.size);
    res.setHeader('Content-Type', 'application/pdf');
    res.setHeader('Content-Disposition', 'attachment; filename=filename.pdf');

    const file = fs.createReadStream(filepath);
    file.pipe(res);
});

Your angular code,

this._http.get(url, {responseType: ResponseContentType.ArrayBuffer}).subscribe( data => {
    var file = new Blob([data.blob()], {type: 'application/pdf'});
    var fileURL = window.URL.createObjectURL(file);
    window.open(fileURL);
});   
Harshal Patil
  • 6,659
  • 8
  • 41
  • 57
  • This solution works if I have a pdf stored in Node and return it to the frontend. However the External API I am calling does not stream me a file it responses with the plain PDF text above, so there is no file to transfer only a string with all the data. Do I need to be converting the Data to a PDF file and then send it? – Schweit Mar 27 '18 at 13:20
  • You can convert string data to arrayBuffer and send it over the API so that way you can directly access pdf in angular – Harshal Patil Mar 27 '18 at 16:15
  • I am trying to implement this, but I am having an issue when tryin to access data.blob(). The error says that blob does not exist on type 'ArrayBuffer' any ideas why @HarshalPatil – d0rf47 Aug 02 '21 at 18:45