如何执行动态加载的JavaScript块?
时间:2020-03-05 18:56:55 来源:igfitidea点击:
我正在一个网页上进行AJAX调用,返回的HTML代码如下:
<div> <!-- some html --> <script type="text/javascript"> /** some javascript */ </script> </div>
我正在将整个内容插入DOM,但是没有运行JavaScript。有办法运行吗?
一些细节:我无法控制脚本块中的内容(因此无法将其更改为可以调用的函数),我只需要执行整个块即可。我无法在响应中调用eval,因为JavaScript位于更大的HTML块中。我可以做某种正则表达式来分离JavaScript,然后在其上调用eval,但这真令人讨厌。有人知道更好的方法吗?
解决方案
回答
如果我们使用响应来填充div或者其他内容,则不必使用正则表达式。我们可以使用getElementsByTagName。
div.innerHTML = response; var scripts = div.getElementsByTagName('script'); for (var ix = 0; ix < scripts.length; ix++) { eval(scripts[ix].text); }
回答
最好的方法可能是直接通过DOM识别并评估脚本块的内容。
不过,我会小心..如果我们实施此操作是为了克服某些异地通话的限制,则可能会打开安全漏洞。
无论我们实施什么,都可以被XSS利用。
回答
一种替代方法是不只是使用InnerHTML将Ajax调用的返回结果转储到DOM中。
我们可以动态插入每个节点,然后脚本将运行。
否则,浏览器仅假定我们要插入文本节点,而忽略脚本。
使用Eval是很邪恶的,因为它需要启动Javascript VM的另一个实例并通过JIT传递字符串。
回答
通过设置元素的innerHTML属性添加的脚本不会执行。尝试创建一个新的div,设置其innerHTML,然后将此新的div添加到DOM中。例如:
<html> <head> <script type='text/javascript'> function addScript() { var str = "<script>alert('i am here');<\/script>"; var newdiv = document.createElement('div'); newdiv.innerHTML = str; document.getElementById('target').appendChild(newdiv); } </script> </head> <body> <input type="button" value="add script" onclick="addScript()"/> <div>hello world</div> <div id="target"></div> </body> </html>
回答
我们可以使用一种流行的Ajax库来为我们本机执行此操作。我喜欢原型。我们可以在Ajax调用中添加evalScripts:true,它会自动发生。