We have a ReactJS web app which uses an iframe to embed PDF in the page. We download the PDF as a byte array, then store it as a blob URL. It works in all browsers except Safari. We use createURLObject which creates a local url like blob:http://domain/guid. If I grab this URL and open it in another tab, it shows the PDF. Not in Safari. It redirects to favorites with a random Guid and fails. It seems Safari has issues with blobs or PDFs. I tried changing it from a blob url to a data URL using a file reader. Only difference is that Safari can render the data url in another tab but not in an iframe. The iframe loads but the body is empty with the message 'no supported plugin found'. Im running out of idea and think Safari just sucks
downloadPDf(customerId) {
this.api.downloadContract(customerId)
.then(response => {
const pdfData = new Blob(response.data.conent, 'application/pdf');
reader.onload = () => {
this.setState({dataUrl : reader.result });
}
reader.readAsDataURL(pdf);
}
Then in the JSX:
<iframe src={this.state.dataUrl} .... />
Once the file reader is loaded, the result will have a data URL containing the RAW data for the PDF.
It looks like something like this: data:application/pdf:byte64:<FILE_CONTENT>
This wont render in the iframe, but pasting it into a new tab will actually render the PDF correctly.
Our original code relied on Blob URLS which is like this:
downloadPDf(customerId) {
this.api.downloadContract(customerId)
.then(response => {
const pdfData = new Blob(response.data.conent, 'application/pdf');
const dataUrl = window.URL.CreateURLObject(blob);
}
This will create a local blob url which looks like: blob:http://localhost/
Pasting this into another tab does not work in Safari. It works in Edge, Chrome, and FireFox.
The downside of using the data URL is the file reader and a callback.