1

I'm working on an application where the user can click a button to generate a PDF. That button makes an ajax call that returns a url to the file. We then make another call to get the file (because it is protected by the user's auth token) and I get this big blob of stuff back. I know it's all the right format because when I go do the same request in Postman and then click the download button it returns the proper pdf.

How do I get the file to download properly in the browser using JavaScript?

I've looked at Download pdf file from ajax response and adapted the second response (with +100 bounty) to fix what the Chrome way should be now but I'm getting a blank PDF (with the right amount of pages, mind you...).

In firefox, I see something popup all of a sudden and then disappear super quickly and no download happens.

Here's my code (super similar to the answer of that other question):

let filename = result.url.split('/')[result.url.split('/').length - 1];
if (typeof window.chrome !== 'undefined') {
    // Chrome version
    let link = document.createElement('a');
    link.href = window.URL.createObjectURL(new Blob([response.data], { type: 'application/pdf' }));
    link.download = filename;
    link.click();
} else if (typeof window.navigator.msSaveBlob !== 'undefined') {
    // IE version
    let blob = new Blob([response.data], { type: 'application/pdf' });
    window.navigator.msSaveBlob(blob, filename);
} else {
     // Firefox version
     let file = new File([response.data], filename, { type: 'application/force-download' });
     window.open(URL.createObjectURL(file));
}

How would I adapt this code further to make it work in 2019 as opposed to 2016 when the original question was written?

Or, how would you suggest going about this in another way while still keeping the same API request flow as I initially described?

georgeawg
  • 48,608
  • 13
  • 72
  • 95
Ethan Brouwer
  • 975
  • 9
  • 32
  • Basically remove the `typeof window.chrome !== 'undefined'` instead check for `document.createElement('a').download === undefined` and execute your IE only block. If this property is available (today all except old IEs), then use your chrome only version, with the one thing that the anchor must be in the document when you call its click() method. Oh and you don't show the AJAX request, but you shouldn't need to generate the Blob yourself, directly fetch it as a Blob (e.g using `XHR2.responseType = 'blob'`) – Kaiido Jun 26 '19 at 06:18
  • I guess I should've added however that I'm using AngularJS' $http service to make the get request. Do you know if it's possible to set the responseType with that? – Ethan Brouwer Jun 26 '19 at 13:21
  • I don't but it seems [others do](https://stackoverflow.com/questions/34149741/how-to-receive-blob-responses-using-angulars-2-angular-http-module) – Kaiido Jun 27 '19 at 00:54

0 Answers0