如何执行动态加载的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,它会自动发生。