Javascript: perhaps for a parent to kill a child iframe if it gets stuck in an infinite loop?

I have an iframe page with external content. I do not want endless loops in the external content to break my entire page. Is there any way around this.

I tried installing something where the parent postMessages child iframe so often, and if the child iframe does not respond for too long, the parent changes the iframes src, but this does not seem to work. The setTimeout parent functions are no longer executed after the start of the iframe loop. Look at my code here (note that it will cause your tab to crash, if you run it, open the console before execution to view the log):

<html> <head> </head> <body> <script type="text/javascript"> var scr = 'script'; var html = '<html><head><script>\n' + ' window.addEventListener("message", answer, false);' + ' function answer() { console.log("answered"); parent.postMessage(\'hi\', \'*\');}' + ' setTimeout("while(1){console.log(\'in loop\')};", 3000)' + "</" + scr + "></head><body>IFRAME</body</html>"; var lastAnswer = (new Date()).getTime(); var iframe = document.createElement('iframe'); queryChild(); window.addEventListener("message", receive, false); function receive() { lastAnswer = (new Date()).getTime(); console.log('got answer'); } function queryChild() { console.log('querying'); if((new Date()).getTime() - lastAnswer > 5000) { console.log('killing'); iframe.src = ''; } else if(iframe.contentWindow){ iframe.contentWindow.postMessage('hi', '*'); } setTimeout(queryChild, 2000); }; document.body.appendChild(iframe); iframe.contentWindow.document.open(); iframe.contentWindow.document.write(html); iframe.contentWindow.document.close(); </script> </body> </html> 

Any suggestions for resolving this issue?

+4
source share
4 answers

My experience with this problem is that if you cannot access the external code before sending it to the iframe (either as a URL or via srcdoc ), the loop will completely interrupt JavaScript execution.

No matter what timeout functionality you implement, it will not be called due to the execution of iframe code, which consumes 100% of the resources, until the browser reports a crash.

Your options:

  • Sanitize the code automatically before adding it to the iframe , which turns out to be impractical, since there are endless ways to loop endlessly and you won’t be able to catch them. You will have to write a script scanner that could detect endless loops without getting lost while scanning the code.
  • To sanitize the code, use a sandbox solution like Google Caja . However, this will change the code structurally if it is not configured to a large extent.
  • In the case of an application with the ability to create virtual environments and monitor them, you can execute the iframe code (say, on a virtual machine), check if the process is blocked and use this result to determine if you can safely set the iframe.src property to the URL your code. This may be the only solution that can guarantee some guarantee that this code will not be blocked immediately (however, there are many ways to have race conditions at some later point in execution, so there will be no sure way to say this will never close the browser).

Summary If you cannot find a way to test the code before showing it in the iframe , you cannot guarantee that the iframe code will not block the browser tab.

+3
source

In a browser, this is very dependent, in some browsers one stream is used for each page (or iframe), in which case your script cannot be executed until the iframe completes (endless loop). Some others have one thread per page (or iframe), and maybe you can do this.

I am sure that if you plan to support enterprise browsers (e.g. IE8), you cannot.

0
source

it

 console.log('killing'); iframe.src = ''; 

Will not kill iframe . according to the same origin policy you cannot manipulate external domains from your domain. Simply changing the src iframe does not cause navigation in the iframe . src will change, but the iframe will not move.

If you get a message from the internal iframe , you must remove the iframe from the document tree and insert a new one in the document tree to kill the iframe using removeChild

 document.body.removeChild(iframe); document.body.appendChild(newiframe); 

Take a look at this simple demo I created here: http://jsbin.com/avodeb/1/

0
source

Try the following:

 <script> document.getElementById('iframeID').onload= function() { //When the iframe loads quickly clearTimeout(killerTimer); // Stop the Killer Timer }; var killerTimer = setTimeout( function() { document.getElementById("iframeID").setAttribute("src",""); //Otherwise, kill the iframe }, 3000 ); </script> 
0
source

Source: https://habr.com/ru/post/1438508/


All Articles