javascriptpdffirefoxiframecross-origin-resource-policy

Firefox throws cross-origin error on iframe with same-origin PDF


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.


Solution

  • 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

    Then, your iframe should use

    <iframe 
      id="pdfIframe"
      src="/pdf/web/viewer.html?file=/example.pdf"></iframe>