0

Although it may be a duplicate question but I have done everything I can without getting the solution. I'm using Node + Express.

We use to send link of PDF file as CDN url in SMS

The link looks like this:

/api/v1/cdn/pdf/24

To get PDf and return, I have this code:

        let parameter = await this.parameterDB.readRecord(where);

        if (parameter) {
            let fileName = parameter.id + '_' + parameter.patient_id + '.pdf';


            // METHOD 1
            let data = fs.readFileSync(constants.PATH.PDFS + fileName);

            res.setHeader('Content-disposition', 'inline; filename="' + fileName + '"');
            res.contentType('application/pdf');
            res.send(data);

            // METHOD 2
            res.writeHead(200, {
                'Content-Type': 'application/pdf',
                'Content-Disposition': 'inline; filename=report_' + fileName,
                'Content-Length': data.length
            });
            res.end(data, 'binary');


            // METHOD 3
            let file = fs.createReadStream(constants.PATH.PDFS + fileName);
            var stat = fs.statSync(constants.PATH.PDFS + fileName);
            res.setHeader('Content-Length', stat.size);
            res.setHeader('Content-Type', 'application/pdf');
            res.setHeader('Content-Disposition', 'inline; filename=' + fileName);
            file.pipe(res);
        } else {
            return this.responseUtil.sendReadResponse(req, res, {
                message: 'not found'
            }, 200);
        }

I all of the above 3 methods, when I click on the link in SMS, it downloads the PDF file instead of opening in web browser (which is annoying for the customers).

File is returned properly.

What can I do here?

Ashutosh
  • 4,371
  • 10
  • 59
  • 105

1 Answers1

0

I assume, by sending the API link in SMS means you want your customers to view the PDF in mobile browser. Browsers can view the PDF file due to the plugins they support or have installed by default, but this is not the case with phone browsers, atleast not all browsers on smartphones support PDF viewer, especially android. I can view PDF files in safari and chrome browser on iPhone though, because they have support for PDF view.

source: https://www.quora.com/Why-does-Chrome-on-Android-not-open-PDF-files-like-Chrome-on-Windows-Linux-can

Any one of the method in your code can show the PDF file on desktop browser with no modification, however when you try to call the API URI on phone browser, you'll see the PDF file getting downloaded as there is no support for that in the browser, instead browser looks for the native application on phone, downloads the file and opens in it. Although there is a way/work-around for this if you want to see the PDF files in the browser using google docs. You can simply embed your URL location of the PDF in the google docs link itself and redirect to it when customer hits your API URI.

source: How to display a PDF via Android web browser without "downloading" first

So you can modify your code something like this:

let parameter = await this.parameterDB.readRecord(where);

if (parameter) {
    res.redirect("https://docs.google.com/gview?embedded=true&url=http://host...your-pdf-path.pdf")
} else {
    return this.responseUtil.sendReadResponse(req, res, {
        message: 'not found'
    }, 200);
}

There is an another alternative for this, although it would require more efforts, but it is worth if you have lots of documents in your application that need to be seen on phone browser. You can make use of PDF.js by Mozilla and create your own custom pdf viewer, this viewer is completely created in vanilla JavaScript and thus, it is supported by almost all browsers. Once you have your own viewer implemented, all you have to do is :

res.sendfFile('show an html file eg index.html', { pdfURL: <path of the pdf file> });

and inside this index.html file you need to pass the path of the pdf file, make use of PDF.js functions to get the document data and create custom viewer. You can use ejs to achieve this in Express JS.

Yatin Gaikwad
  • 1,140
  • 1
  • 13
  • 23