Currently using FileReader to open and view a PDF that works on Chrome. However, when the pdf is opened on Safari and you click the download button, nothing happens.
var reader = new FileReader();
reader.onloadend = function(e) {
$window.location.href = reader.result;
}
reader.readAsDataURL(file);
After having spent an entire day working on a similar issue, I understood where the problem was so I can now share my knowledge with you.
Basically, this kind of problems are generated when you render the Blob
inside the already opened browser tab so your page url changes in something like:
blob:http://localhost:8080/9bbeffe1-b0e8-485d-a8bd-3ae3ad9a0a51
The wrong procedure for requiring a pdf would be something like this:
var fileBlob = new Blob([response.data], {type: 'application/pdf'});
window.location.hfref = fileBlob;
Why doesn't this work?
Well, you can see the pdf rendered on the page so you might be fooled to thinking that your pdf is loaded fine. However, if you either try to refresh the page or download the pdf on your machine, it doesn't work.
WTH?
So, initially I was really thinking of some sort of black magic going around the browser, then I figured out the problem:
The file doesn't exist but its only cache stored inside the browser. So, when you generate the blob and you redirect your current tab to point to the generated blob url, you lose the cache.
Now everything makes sense right?
- You request a file on the server
- The browser stores the buffer inside the tab
- You point your page url to read the buffer
- You see the pdf but at the same time, you lose the buffer information
The only think you can do, is opening the Blob url in a new tab with:
window.open(fileBlob, '_blank');
Problem solved.
After going through the same scenario as @andreasonny83 answer, plus having the headache issue of an adblock that closed the tab opened with window.open
in a split second, I found a solution that worked for me. Not sure if it works in Safari since i do not have a mac to test it. Tried on Firefox and Chrome. I'm sure if it doesn't work on IE or Safari there's a workaround. What I did was using the embed html5 component providing as a src, an URL.createObject(blob) object. That way I was able to render/refresh and download the pdf.
// pdfBlob is the pdf fetched from the API as a blob.
pdf = URL.createObjectURL(pdfBlob)
Then you just embed that pdf into an embed
tag like this:
<div style={{ width: '100%', height: '100%' }}>
<embed src={pdf} type='application/pdf' width='100%' height='100%' />
</div>
The key was to use the html5 tag embed. It worked nicely. Of course you need to find a way to set the embed
src attribute. I'm using react and redux so i use jsx, but you can use plain vanilla javascript or whatever you like.