通过AJAX以JSON格式返回的动态生成的Javascript在附加时将不会执行

Dynamically generated Javascript returned via AJAX in JSON format will not execute when appended

本文关键字:执行 Javascript JSON AJAX 格式 返回 动态 通过      更新时间:2023-09-26

我有一个网页,它向PHP脚本发出AJAX请求。该PHP脚本使用一个有效的JSON对象进行响应,并将Content-type标头设置为application/json

JSON格式如下(如console.log(JSON.stringify(data))所报告,其中data是JSON响应):

{
    "content": "<script type='"text/javascript'">console.log('"test'");</script>"
}

然后,我创建了一个类为"content"的div(记住data是我的AJAX responseText JSON对象):

var content = document.createElement("div");
content.setAttribute("class", "content");
content.innerHTML = data.content;

最后,我将内容div附加到站点上现有的div中。

existingDiv.appendChild(content);

我在Google Chrome开发工具的elements选项卡中检查了源代码,因为它很好地显示了什么是实际的DOM节点,什么只是文本。脚本块显示为一个DOM节点。

不幸的是,脚本没有执行——console.log("test");不会将test输出到开发人员工具控制台。

到目前为止,我看到的唯一选择是使用eval(),我正试图像瘟疫一样避免它。此外,我的内容可能不仅仅包含一个脚本块。它还可以包含其他HTML标记。

我错过了什么?如何让这个动态添加的Javascript块执行?

jQuery解决方案是可以接受的。

一个可能的解决方案是使用new Function()作为:

$(document).ready(function(){
   var script = "window.alert('hi')";
   new Function(script)();
});

至于为什么你的脚本没有执行,这是@Pointy建议的(但不是完全+一种规避的方法),如以下代码所示:

<script type='text/javascript'>
$(document).ready(function()
{
    $("<script type='text/javascript'>window.alert('hi');<'/script>").appendTo(document.body); // this will work
    var container = document.createElement("div"); // this won't work
    container.innerHTML = "<script type='text/javascript'>window.alert('hi');<'/script>";
    document.body.appendChild(container);
    var script = document.createElement("script"); // this will
    script.innerHTML = "window.alert('hi');";
    document.body.appendChild(script);
});
</script>

编辑:添加了请求的单元测试:http://jsperf.com/eithed-hvsa

使用$.getScript()简单、可计算、直接:

http://api.jquery.com/jQuery.getScript/

(很明显,您必须修改生成包含jscode和change头的json的服务器脚本)

设置.innerHTML不评估<script>标记;这不是浏览器的作用。

如果需要返回要执行的JavaScript,最好将其作为字符串发送(不带<script>标记),这样就可以轻松地将其传递给eval()

edit如果您使用jQuery而不是直接设置innerHTML(也就是说,如果您使用$(something).html())执行此操作,并且您将内容直接添加到DOM中的某个元素(即,不仅仅是已实例化但未附加到DOM的元素),则jQuery将主动查找和提取<script>内容并对其进行评估。