goryef
goryef

Reputation: 1489

NodeJs/Express display pdf file in browser

I am working on NodeJs/Express project and need to show in the browesr pdf file that is stored in

/public/images

Here is relevant router code:

router.post('/show_file', async (req,res)=>{
  try {
     let path = './public/images/1.pdf'
     var data =fs.readFileSync(path);
     res.contentType("application/pdf");
     res.send(data);
   } catch (err) {
     res.status(500)
     console.log(err)
     res.send(err.message)
   }
})

I don't get any errors but nothing is happening ie.browser is not opening etc. Thanks in advance for any guidance.

Upvotes: 2

Views: 6992

Answers (1)

Thiago Coutinho
Thiago Coutinho

Reputation: 311

The first change that I would do is to remove the async. It will just mess out the code with unneeded Promises.

Second, I removed the need to catch the exception, verifying the existence of the file with fs.existsSync(path). Try to not to rise exceptions as often as possible. If you know something can rise an exception, test it.

Last, and most important, I created a reading stream of the file and piped the result to the response with fs.createReadStream(path).pipe(res). This way, the client recieves the file as it is read and your memory is spared. Great for large files.

Reading a file can be memory intensive, so loading it all in memory is a bad practice. You just need a handfull of request to overload your machine.

You can read more on the pipe method here.

In this example, any GET call to /router/show_file will return the pdf.

const express = require('express')
const app = express()
const fs = require('fs')
const router = express.Router()

router.get('/show_file', (req, res) => {
    const path = './public/images/1.pdf'
    if (fs.existsSync(path)) {
        res.contentType("application/pdf");
        fs.createReadStream(path).pipe(res)
    } else {
        res.status(500)
        console.log('File not found')
        res.send('File not found')
    }
})

app.use('/router', router) // Here we pass the router to the app with a path

app.listen(9999, () => console.log('Listening to port 9999'))

Upvotes: 7

Related Questions