Search code examples
htmliframeinternet-explorer-11sandboxmicrosoft-edge

HTML as sandboxed iframe's `src` (IE11/Edge)


With HTML5, is there any way in IE11/Edge to populate a sandboxed iframe (<iframe sandbox></iframe>) with HTML other than using a src url? I am looking for a solution like srcdoc which works with all other modern browsers.

Using src with a data URI is not an option according to Microsoft as it "cannot be used [to] populate frame or iframe elements." Surprisingly, this does works for me in Edge but only for data URIs with less than 4096 characters.

All other options that I have found, e.g. in Alternatives to iframe srcdoc? and Html code as IFRAME source rather than a URL do not work for a sandboxed iframe.


Solution

  • Assuming usage of <iframe sandbox="allow-scripts"> is desired or acceptable, a possible workaround would be using window.postMessage() with the following setup:

    index.html:

    <!doctype html>
    <html>
    <body>
      <iframe onload="connectIframe()" sandbox="allow-scripts" src="iframeConnect.html" name="srcdocloader"></iframe>
      <script>
    
    var SRCDOC_HTML = '<html><body><script src="https://code.jquery.com/jquery-3.2.1.js"><\/script><script>console.log("loaded srcdoc and dependencies", jQuery);<\/script><h1>done!</h1></body></html>';
    var loaded;
    
    function connectIframe (event) {
      if (!loaded) {
        loaded = true;
        window.frames.srcdocloader.postMessage(SRCDOC_HTML, '*');
      } else {
        onloadSrcdoc();
      }
    }
    
    function onloadSrcdoc () {
      // ...
    }
    
      </script>
    </body>
    </html>
    

    iframeConnect.html:

    <!doctype html>
    <script>
    window.addEventListener("message", handler);
    function handler(event) {
      if (event.source === window.parent) {
        window.removeEventListener("message", handler);
        document.write(event.data);
        document.close();
      }
    }
    </script>
    

    Note that the iframe's onload event will be triggered two times. The second time will be after the srcdoc html and all its dependencies got loaded.