1

I am trying to serve a PDF file to the user, and I have a string containing the bytes in the PDF file. I want to write these bytes to the browser so the user can download the PDF file. However when I do this:

document.open('application/pdf');
document.write(myBytes);

I just get the bytes rendered as text, that is, they are in an HTML page (see screenshots). I want only the bytes specified to be rendered, without any HTML surrounding them. How can I do this?

PDF bytes rendered in an HTML page

HTML source of my "PDF"

enter image description here

3
  • The DOM tree is not the best place to inspect raw output. What do "Network/ Response" or "View/ Source" menu items show? Commented Jun 17, 2020 at 19:58
  • "View source" gives me the HTML for the page that I navigated from to get to the PDF; I suppose this is because I did the rewriting of the page in JavaScript so the source never actually got updated. I'm not entirely sure what you mean by "network/response", but I'll go ahead and attach some screenshots from the network tab in the browser dev tools. Commented Jun 18, 2020 at 15:53
  • You've shared the "Headers" secondary tab in the "Network" tab. "Response" is close to it (it's the fourth tab in Firefox). You're getting HTML because that's exactly what document represents, an HTML document—but PDF is not HTML. See Józef's answer for a way to do it. Commented Jun 18, 2020 at 16:13

1 Answer 1

1

You can force file download with anchor && download attribute trick or use iframe

Here's an example below

Snippet doesn't work because of sandboxed environment.

const pdfView = document.querySelector("#pdfView");

fetch("https://cors-anywhere.herokuapp.com/https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf")
  .then(response => response.blob())
  .then(blob => blob.arrayBuffer())
  .then(myBytes => {
    const totalBlob = new Blob([myBytes], { type: 'application/pdf' });
    const url = window.URL.createObjectURL(totalBlob);
    const anchor = document.createElement("a");
    anchor.href = url;
    anchor.download = `document.pdf`;
    anchor.click();
    anchor.textContent = 'Download'
    document.body.appendChild(anchor);

    pdfView.src = url;  
  })
<iframe id="pdfView" src="" type="application/pdf" width="100%" height="100%" style="overflow: auto;">
    </iframe>

Sign up to request clarification or add additional context in comments.

4 Comments

Hmm... But the PDF I have is not accessible via a URL; it's just a string containing a bunch of bytes. If I were to make it accessible via a URL I'd have to worry about assigning it the right permissions so no one can go in and punch in a URL to look at someone else's PDF.
You can use code what is inside then(myBytes => { function in this case
@ekolis fetch() is only used to provide a runnable self-contained example, the key point is creating a Blob and generating a data URI for it.
Thanks! So now I have a five page blank PDF being downloaded, now to figure out why it's blank...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.