如何执行动态加载的 JavaScript 块?

IT技术 javascript ajax
2021-01-27 02:28:14

我正在一个网页上工作,我在其中进行 AJAX 调用,该调用返回一大块 HTML,例如:

<div>
  <!-- some html -->
  <script type="text/javascript">
    /** some javascript */
  </script>
</div>

我将整个内容插入到 DOM 中,但 JavaScript 并未运行。有没有办法运行它?

一些细节:我无法控制脚本块中的内容(因此我无法将其更改为可以调用的函数),我只需要执行整个块。我无法对响应调用 eval,因为 JavaScript 位于更大的 HTML 块中。我可以做某种正则表达式来分离 JavaScript,然后对它调用 eval,但这很糟糕。有人知道更好的方法吗?

6个回答

通过设置元素的innerHTML 属性添加的脚本不会被执行。尝试创建一个新 div,设置其 innerHTML,然后将这个新 div 添加到 DOM。例如:

<html>
<头>
<script type='text/javascript'>
函数 addScript()
{
    var str = "<script>alert('我在这里');<\/script>";
    var newdiv = document.createElement('div');
    newdiv.innerHTML = str;
    document.getElementById('target').appendChild(newdiv);
}
</脚本>
</头>
<身体>
<input type="button" value="添加脚本" onclick="addScript()"/>
<div>你好世界</div>
<div id="目标"></div>
</正文>
</html>
此脚本在 IE 7 中不起作用。IE 7 的 appendChild 函数似乎存在错误。
2021-04-02 02:28:14

如果您使用响应来填充 div 或其他内容,则不必使用正则表达式。您可以使用 getElementsByTagName。

div.innerHTML = response;
var scripts = div.getElementsByTagName('script');
for (var ix = 0; ix < scripts.length; ix++) {
    eval(scripts[ix].text);
}

虽然@Ed 接受了答案。不适用于当前版本的 Firefox、Google Chrome 或 Safari 浏览器我设法熟练他的示例以调用动态添加的脚本。

必要的更改仅在于将脚本添加到 DOM 的方式。添加它innerHTML的技巧不是添加它,而是创建一个新的脚本元素并将实际脚本内容添加innerHTML到创建的元素,然后将脚本元素附加到实际目标。

<html>
<head>
<script type='text/javascript'>
function addScript()
{
    var newdiv = document.createElement('div');

    var p = document.createElement('p');
    p.innerHTML = "Dynamically added text";
    newdiv.appendChild(p);

    var script = document.createElement('script');
    script.innerHTML = "alert('i am here');";
    newdiv.appendChild(script);

    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>

这适用于 Firefox 42、Google Chrome 48 和 Safari 9.0.3

另一种方法是不只是使用 InnerHTML 将 Ajax 调用的返回转储到 DOM 中。

您可以动态插入每个节点,然后脚本将运行。

否则,浏览器只会假设您正在插入一个文本节点,而忽略脚本。

使用 Eval 相当邪恶,因为它需要启动另一个 Javascript VM 实例并对传递的字符串进行 JIT。

如果您解释如何动态插入每个节点,那就太好了。
2021-03-17 02:28:14

最好的方法可能是直接通过 DOM 识别和评估脚本块的内容。

不过,我会小心……如果您正在实施此功能以克服某些场外呼叫的限制,那么您将打开一个安全漏洞。

你实现的任何东西都可能被用于 XSS。

如果我错了,请纠正我,但根据我在这种情况下理解 XSS 漏洞的方式,如果您担心有人能够访问其他人的在线帐户,从而能够窃取敏感信息,这只是一个问题信息,但如果用户无法登录该站点,则不必担心。
2021-04-12 02:28:14