The correct JavaScript execution method returned via AJAX (no jQuery)

Let's say I get a response to a request to load AJAX data using a combination of JavaScript and HTML, for example:

<script>window.alert('Hello World!');</script> <p>This is a paragraph. Lorem ipsum dolor sit amet...</p> 

If I simply put this answer in a div or other container, the script will not be executed automatically. I know that this can be done using the eval() function (as indicated in the example below), but eval is evil, so how can I do it right? Note: I do not use jQuery.

The following is an example AJAX bootloader:

 function Load(id,url){ var ajax=new XMLHttpRequest(); ajax.onreadystatechange=function(){ if(ajax.readyState!=4)return; var obj=document.getElementById(id); if(!obj)return; obj.innerHTML=ajax.responseText; // load any scripts var s=obj.getElementsByTagName('script'); for(var i=0;i<s.length;++i)window.eval(s[i].innerHTML); // <-- bad } ajax.open("GET",url,true); ajax.send(null); } 
+4
source share
3 answers

Please note that you accept data from the user and run it in the context of the script on your site. This way, the script can do everything that JavaScript running in your browser / domain can work (including theft of cookies, XSS, malware, etc.).

The only thing you can really do to reduce the risks is not eval () the content provided by the user. I would suggest considering the following alternatives:

+3
source

The eval in this scenario is not particularly evil, it is not much different from what it says dynamically adding a script tag that pulls out the .js file and runs it. However, there are other options, for example, you can dynamically create a script tag, create a node text with the contents of the script tag that you removed, and add it to the document. Unlike the innerHTML method, which actually launches the content. In fact, the only advantage over eval is that you can get a more meaningful stack trace, etc., if it works or has a syntax error.

 var newScriptTag = document.createElement('script'); newScriptTag.appendChild(document.createTextNode( origScriptTag.innerHTML) document.body.appendChild(newScriptTag); 
+2
source

I solved this today by putting my JavaScript at the bottom of the HTML response.

I had an AJAX request that returned a bunch of HTML that was displayed in the overlay. I needed to attach a click event to a button in the returned HTML / overlay response. On a regular page, I would wrap my JavaScript in "window.onload" or "$ (document) .ready" so that it binds the event handler to the DOM object after the DOM for the new overlay has been rendered, but because it was an AJAX response and not a new page load, this event never occurred, the browser never executed my JavaScript, my event handler never attached to the DOM element, and my new functionality did not work. Again, I decided to "execute JavaScript in the AJAX response problem", not using "$ (document) .ready" at the beginning of the document, but placing my JavaScript at the end of the document and executing it after the HTML / DOM.

0
source

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


All Articles