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

时间:2013-02-08 14:02:14

标签: javascript jquery ajax

我有一个向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解决方案是可以接受的。

3 个答案:

答案 0 :(得分:1)

设置.innerHTML不评估<script>代码;它不是什么浏览器。

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

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

答案 1 :(得分:1)

使用$.getScript()简单,可缓存,直截了当:

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

(显然你必须修改生成包含jscode&amp; change headers的json的服务器脚本)

答案 2 :(得分:1)

可能的解决方案是使用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