I have an iframe that's set to display a PDF loaded from the same origin.
<iframe id="pdfIframe" src="/example.pdf"></iframe>
When I run this JS to check if the iframe is loaded yet, I get a SecurityError
or DOMException
in Firefox:
iframeReady(document.getElementById('pdfIframe'), () => {
console.log('iframe loaded')
))
/**
* Execute callback when iframe is *actually* loaded. Ignores load events for
* the "dummy" document that's loaded when an iframe is added to the DOM, and
* before the src is loaded.
*
* Adapted from an answer on StackOverflow:
* https://stackoverflow.com/a/24603642/877574
*/
function iframeReady(iframe, fn) {
checkLoaded()
function checkLoaded() {
const doc = iframe.contentDocument || iframe.contentWindow?.document
// We can tell if there is a dummy document installed because the dummy document
// will have an URL that starts with "about:". The real document will not have that URL
if (doc && doc.URL.indexOf("about:") !== 0) {
// set event listener for DOMContentLoaded on the new document
doc.addEventListener("DOMContentLoaded", fn)
} else {
// still same old original document, so keep looking for content or new document
setTimeout(checkLoaded, 1)
}
}
}
I know one may think perhaps the error is occurring because the JS runs while the iframe has loaded about:blank
. But I've verified that's not the case. After the iframe has loaded the PDF I can run this and it triggers the exception:
pdfIframe.contentDocument // null
pdfIframe.contentWindow.document // triggers exception
The same code works in Chrome.
When using the built-in pdf viewer in Firefox to load a pdf, the iframe ends up with domain === "pdf.js"
- therefore it is not same origin as the parent, therefore the issue.
There are issues relating to this in Mozilla's bugzilla - but the MAIN (or only) talking point is the inability to call .print()
to print the PDF in an iframe
This is apparently at least partially addressed - e.g. pdfIframe.contentWindow.print()
works.
There are also some other methods/properties are also available, but not document
One solution is to
pdf.js
(it's a zip containing files by the way, it's not a single JS file) from https://mozilla.github.io/pdf.js/getting_started/#downloadpdf
Then, your iframe should use
<iframe
id="pdfIframe"
src="/pdf/web/viewer.html?file=/example.pdf"></iframe>