Downloaded .pdf files are corrupted when using expressjs Downloaded .pdf files are corrupted when using expressjs express express

Downloaded .pdf files are corrupted when using expressjs


I had corruption when serving static pdfs too. I tried everything suggested above. Then I found this:https://github.com/intesso/connect-livereload/issues/39In essence the usually excellent connect-livereload (package ~0.4.0) was corrupting the pdf.So just get it to ignore pdfs via:

app.use(require('connect-livereload')({ignore: ['.pdf']}));

now this works:

app.use('/pdf', express.static(path.join(config.root, 'content/files')));

...great relief.


Here is a clean way to serve a file from express, and uses an attachment header to make sure the file is downloaded :

var path = require('path');var mime = require('mime');app.get('/download', function(req, res){  //Here do whatever you need to get your file  var filename = path.basename(file);  var mimetype = mime.lookup(file);  res.setHeader('Content-disposition', 'attachment; filename=' + filename);  res.setHeader('Content-type', mimetype);  var filestream = fs.createReadStream(file);  filestream.pipe(res);});


There are a couple of ways to do this:

  1. If the file is a static one like brochure, readme etc, then you can tell express that my folder has static files (and should be available directly) and keep the file there. This is done using static middleware:app.use(express.static(pathtofile));Here is the link: http://expressjs.com/starter/static-files.html

Now you can directly open the file using the url from the browser like:

window.open('http://localhost:9000/assets/exports/receipt.pdf');

or

res.redirect('http://localhost:9000/assets/exports/receipt.pdf'); 

should be working.

  1. Second way is to read the file, the data must be coming as a buffer. Actually, it should be recognised if you send it directly, but you can try converting it to base64 encoding using:

    var base64String = buf.toString('base64');

then set the content type :

res.writeHead(200, {                    'Content-Type': 'application/pdf',                    'Content-Length': stat.size                });

and send the data as response.I will try to put an example of this.

EDIT: You dont even need to encode it. You may try that still. But I was able to make it work without even encoding it.

Plus you also do not need to set the headers. Express does it for you. Following is the Snippet of API code written to get the pdf in case it is not public/static. You need API to serve the pdf:

router.get('/viz.pdf', function(req, res){    require('fs').readFile('viz.pdf', function(err, data){        res.send(data);    })});

Lastly, note that the url for getting the pdf has extension pdf to it, this is for browser to recognise that the incoming file is pdf. Otherwise it will save the file without any extension.