Search code examples
jqueryiframejquery-eventssandbox

How to append jQuery events to an iframe with sandbox?


I have an iframe which loads local pages (proxy): I need the Javascript in these pages not to be executed (I am already executing it on the server, executing it again in the client leads to double execution, therefore bad).

I can achieve this by using the new "sandbox" argument.

The catch is that I need to be able to add events from the main window to the iframe contents. This does not seem to work.

I prepared an example using jsfiddle.

<iframe 
id='iframe1' 
sandbox='allow-top-navigation allow-same-origin allow-forms'
srcdoc='<html><head></head><body><div id="test">iframe1</div><script>document.body.style.backgroundColor="yellow"</script></body></html>'>
</iframe>

<iframe
id='iframe2'
srcdoc='<html><head></head><body><div id="test">iframe2</div><script>document.body.style.backgroundColor="yellow"</script></body></html>'>
</iframe>
$('iframe').load(function() {
    var id = this.id;

    //this works in both iframes
    $(this).contents().find("#test").html(id+" says gnek!");

    //I need this to work for iframe 1, too.
    $(this).contents().on("click", function(event) { 
        alert("clicked "+id);
    });
});

As you can see, frame1 is sandboxed and does not execute internal JS (background does not become yellow). However, I can change its contents using JS in the parent window.

Is there a way to add events, too? If not, what would be the best way to load a page into an iframe without letting it execute its javascript?


Solution

  • Attaching events to the content of a sandboxed iframe is the same as running the javascript from the iframe, hence it cannot be done.

    I solved the problem of stopping JS execution by prepending in the <head> of the document the following:

    <script>Function.prototype.call = Function.prototype.apply = function(){};</script>
    

    EDIT: it seems like this is not enough. I finally decided to simply strip the <script>blocks from the document.