Nodejs : How to download a pdf file from a REST API?

Viewed 3508

There is an API with method GET.

https://api.download.com/getxxxxxxx/id

The response is not in the JSON format. It is a PDF(Content-Type: application/pdf). The header of the response

Date: Fri, 28 Aug 2020 16:45:35 GMT
Server: Apache/2.4.18 (Ubuntu)
X-Content-Type-Options: nosniff
Expires: Sun, 19 Nov 1978 05:00:00 GMT
Cache-Control: no-cache, must-revalidate, post-check=0, pre-check=0
X-Content-Type-Options: nosniff
Vary: Accept
Content-Length: 955006
Content-Type: application/pdf

I have tried this way

const assessmentDetails = {
        method: 'get',
        url: 'https://api.download.com/getxxxxxxx/id',
        json: false,
        headers: {
            'api-key': ApiKey.assessmentApikey
        }
    };

    const file_name = uuid + "_summary_report.pdf"
    const file = fs.createWriteStream("./reports/" + file_name);
   
       http.get(assessmentDetails, function (res) {

        file.on('open', function () {            
             file.pipe(res);
             console.log.info('download completed: ' + file);
         });

        file.on('error', function (err) {
             console.log.error('' + err);
        });

    });

But it is not writing the pdf file. I can see a corrupted file. Please suggest to me, how to solve this issue. How to save PDF files as the response of an API in node js?

Edit:

Tried the following way as per @eol's answer. The file is downloading But got an HTTP parse error.

        const file_name = uuid + "_summary_report.pdf"
        const file = fs.createWriteStream("./reports/" + file_name);

        try {
            https.get(url, assessmentDetails, function (res) {
                res.pipe(file);

            }).on('response', function (data) {
                res.json({
                    statuscode: 200,
                    message: 'File downloaded successfully',
                });
            })
        }
        catch (error) {
            res.json({
                statuscode: 500,
                message: 'Something went wrong',
                error: error
            });
        }

Error in the console

"level":"error","message":"uncaughtException: Parse Error: Expected HTTP/\nError: Parse Error: Expected HTTP/\n    at TLSSocket.socketOnData (_http_client.js:469:22)\n    at TLSSocket.emit (events.js:315:20)\n    at TLSSocket.EventEmitter.emit (domain.js:483:12)\n    at addChunk (_stream_readable.js:295:12)\n    at readableAddChunk (_stream_readable.js:271:9)\n    at TLSSocket.Readable.push (_stream_readable.js:212:10)\n    at TLSWrap.onStreamRead (internal/stream_base_commons.js:186:23)","stack":"Error: Parse Error: Expected HTTP/\n    at TLSSocket.socketOnData (_http_client.js:469:22)\n    at TLSSocket.emit (events.js:315:20)\n    at TLSSocket.EventEmitter.emit (domain.js:483:12)\n    at addChunk (_stream_readable.js:295:12)\n    at readableAddChunk (_stream_readable.js:271:9)\n    at TLSSocket.Readable.push (_stream_readable.js:212:10)\n    at TLSWrap.onStreamRead (internal/stream_base_commons.js:186:23)",

Screenshot - https://ibb.co/6tfkTZG

1 Answers

You need to change http to https since your request url is defined as https://.... Further, you need to pipe the response stream to the file-stream, not the other way round:

const fs = require('fs');
const httpLib = require('http') // exchange this for 'https' if your url is https://...

const assessmentDetails = {
    headers: {
        'api-key': ApiKey.assessmentApikey
    }
}

const fileName = uuid + "_summary_report.pdf"
const file = fs.createWriteStream("./reports/" + fileName);

const request = httpLib.get("http://api.download.com/getxxxxxxx/id",
    assessmentDetails,
    (response) => {
        response.pipe(file);
    });
Related