Express: Blank PDF when served from Express

Created on 25 Feb 2016  路  5Comments  路  Source: expressjs/express

Similar to #1555 but that one was closed so not sure if my comment will get any attention.
Copying my comment from there.

I am running into similar issue with my first ever nodejs service. I have following:


var headers = {} 
///Setting some custom headers for authentication

var urlObj = new URL( url );
var options = {
            host: urlObj.host,
            path: urlObj.pathname + urlObj.query,
            headers: headers
 };
 http.get( options, function( response ) {
            var body = '';
            response.on( 'data', function( data ) {
                body += data;
             } );

             response.on( 'end', function() {
                  res.set( 'Content-Type', 'application/pdf' );
                  res.send( new Buffer( body, 'binary' ) );
             } );
 } );

But I see a blank PDF with the correct number of pages and browser renders it as a PDF but all pages are empty.
Accessing the url directly shows the right pdf so the pdf is fine.
Any input will be really appreciated.

Thanks

4.x question

Most helpful comment

Thanks. Yes request module really simplified the code a lot to basically one liner.

request.get( { url: url, headers: headers } ).pipe( res );

All 5 comments

For stuff like this I usually use the request module, you could try something like this:

var request = require('request');
var app = require('express')();

app.get('/my-pds.pds', function (req, res) {
  var opts = {} // ...
  request.get(opts).pipe(res);
});

Request and express handle the rest.

Also, fyi, people who follow the repo also get notifications for comments on closed issues, so your other comment would get seen.

Also, fyi, people who follow the repo also get notifications for comments on closed issues, so your other comment would get seen.

But I would say it's best practice to open a new issue unless you have something specific to add to the other issue :) More often than not, a "me too" ends up with a different answer, and the original issue author gets emails for something they don't care about. It also means that even if we get the emails, we can't forget to answer you, since we'll see an open issue :)

Good to know, thanks @dougwilson :)

And of course, just to iterate on the answer from @wesleytodd, hopefully his answer should fix your issue, @vinodmehta. The reason you are seeing odd behavior is because the way you are piping the PDF file ends up corrupting the file, because the operation body += data; will actually cause the data Buffer to get decoded as if it was UTF-8 into a string, which will corrupt binary data.

The request module is a really good approach, and I would recommend that, as it's very straight-forward and simple :)

If you wanted to tweak your original code to see where you went wrong, here is a simple tweak that should address the binary data corruption:

var headers = {} 
///Setting some custom headers for authentication

var urlObj = new URL( url );
var options = {
            host: urlObj.host,
            path: urlObj.pathname + urlObj.query,
            headers: headers
 };
 http.get( options, function( response ) {
            var body = []; // we're going to store all the chunks of binary data
            response.on( 'data', function( data ) {
                body.push(data); // build up an array of Buffers
             } );

             response.on( 'end', function() {
                  res.set( 'Content-Type', 'application/pdf' );
                  res.send( Buffer.concat(body) ); // join all the buffers together as a binary blob
             } );
 } );

Thanks. Yes request module really simplified the code a lot to basically one liner.

request.get( { url: url, headers: headers } ).pipe( res );
Was this page helpful?
0 / 5 - 0 ratings