kxhitiz
kxhitiz

Reputation: 1949

Streaming pdf file from node server randomly just shows binary data on browser

I have a node app (specifically sails app) that is serving pdf file. My code for serving file looks like this.

request.get(pdfUrl).pipe(res)

And when I view the url for pdf, it renders the pdf fine. But sometimes, it just renders the binary data of pdf on browser like given below.

%PDF-1.4 1 0 obj << /Title (��) /Creator (��wkhtmltopdf

I am not able to figure out why is it failing to serve the pdf correctly just randomly. Is it chrome thing? or Am I missing something?

Upvotes: 8

Views: 1526

Answers (5)

Angad
Angad

Reputation: 2823

Leaving this here in the hope that it helps somebody - I have had similar issues multiple times and its either of two things:

  1. You're using an HTTP connection to an HTTPS delivery (this is typical with websockets, where you must specify :443 in addition to the wss.
  2. request's encoding parameter is serving plaintext instead of objects. This is done by setting encoding to null as follows: request({url: myUrl, encoding: null}).
  3. Content types in headers - steering clear of this since it's obvious/others have covered this substantially enough already :)

I am pretty sure you're facing this due to (2). Have a look at https://github.com/request/request

encoding - Encoding to be used on setEncoding of response data. If null, the body is returned as a Buffer. Anything else (including the default value of undefined) will be passed as the encoding parameter to toString() (meaning this is effectively utf8 by default). (Note: if you expect binary data, you should set encoding: null.)


Since, the aforementioned suggestions didn't work for you, would like to see forensics from the following:

  • Are files that fail over a particular size? Is this a buffer issue at some level?
  • Does the presence of a certain character in the file cause this because it breaks some of your script?
  • Are the meta-data sections and file-endings the same across a failed and a successful file? How any media file is signed up-top, and how it's truncated down-bottom, can greatly impact how it is interpreted

Upvotes: 2

jaygeek
jaygeek

Reputation: 1162

I would suggest trying both of these:

Content-Type: application/pdf Content-Disposition: attachment; filename="somefilename.pdf"

(or controlling Mime Type in other ways: https://www.npmjs.com/package/mime-types)

Upvotes: 0

Eugene
Eugene

Reputation: 2878

When Chrome downloads the PDF as text I would check the very end of the file. The PDF file contains the obligatory xref table at the end. So every valid PDF file should end with the following sequence: %EOF. If not then the request was interrupted or something gone wrong.

Upvotes: 1

Mitja Gustin
Mitja Gustin

Reputation: 1781

You also need HTTP header:

Content-Disposition:inline; filename=sample.pdf;

And

Content-Length: 200

Did you try to save what ever binary stuff you get on disk and open it manually by PDF reader? It could be corrupt.

Upvotes: 0

Ownaginatious
Ownaginatious

Reputation: 797

You may need to include the content type header application/pdf in the node response to tell the recipient that what they're receiving is a PDF. Some browsers are smart enough to determine the content type from the data stream, but you can't assume that's always the case.

Upvotes: 1

Related Questions