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

通过AJAX以JSON格式返回的动态生成的Javascript在追加时不会执行,javascript,jquery,ajax,Javascript,Jquery,Ajax,我有一个向PHP脚本发出AJAX请求的网页。该PHP脚本使用有效的JSON对象进行响应,并将内容类型标题设置为应用程序/JSON JSON格式如下(由console.log(JSON.stringify(data))报告,其中data是JSON响应): 最后,我将content div附加到站点上的现有div existingDiv.appendChild(content); 我在Google Chrome开发者工具的元素选项卡中检查源代码,因为它很好地显示了什么是实际的DOM节点,什么只是文

我有一个向PHP脚本发出AJAX请求的网页。该PHP脚本使用有效的JSON对象进行响应,并将
内容类型
标题设置为
应用程序/JSON

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

最后,我将content div附加到站点上的现有div

existingDiv.appendChild(content);
我在Google Chrome开发者工具的
元素
选项卡中检查源代码,因为它很好地显示了什么是实际的DOM节点,什么只是文本。脚本块显示为DOM节点

不幸的是,脚本没有执行-
console.log(“test”)不会将
测试
输出到开发人员工具控制台

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

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


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

设置
。innerHTML
不评估
标记;这不是浏览器的功能

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


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

设置
.innerHTML
不计算
标记;这不是浏览器的功能

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

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

使用
$.getScript()
简单、可计算、直截了当:

(显然,您必须修改生成包含jscode的json的服务器脚本&更改头)

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


(显然,您必须修改生成包含jscode的json的服务器脚本并更改标题)

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

$(文档).ready(函数()
{
$(“window.alert('hi');”).appendTo(document.body);//这将起作用
var container=document.createElement(“div”);//这不起作用
container.innerHTML=“window.alert('hi');”;
文件.正文.附件(容器);
var script=document.createElement(“脚本”);//这将
script.innerHTML=“window.alert('hi');”;
document.body.appendChild(脚本);
});

编辑:添加了一个请求的单元测试:

一个可能的解决方案是使用
新函数()

$(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>

$(文档).ready(函数()
{
$(“window.alert('hi');”).appendTo(document.body);//这将起作用
var container=document.createElement(“div”);//这不起作用
container.innerHTML=“window.alert('hi');”;
文件.正文.附件(容器);
var script=document.createElement(“脚本”);//这将
script.innerHTML=“window.alert('hi');”;
document.body.appendChild(脚本);
});

编辑:添加了一个请求的单元测试:

基于任意字符串注入脚本标记与使用
eval()
完全相同,至少在应该避免
eval()
的原因方面是这样的。@MCL您能在回答中对此进行更多扩展吗?我可以通过询问您为什么要避免
eval()
“就像瘟疫一样“然后告诉你,注入任意的
标记也有同样的风险。基本上,当使用这两种方法中的一种时,您正在做相同的事情:从internet上的某个位置获取任意字符串,并可靠地执行它们。我假设您已经知道脚本的位置在同一个域上,并且它的内容可以信任。我主要担心的是
eval
被认为是“邪恶的”,而且我听说它的性能非常慢。不过,你的观点很好,也很有说服力。如果性能是你唯一关心的问题,那么脚本注入是更好的选择。我写了一首很快的小提琴,我必须承认,我有点惊讶。尽管这两种方法都使用某种“黑客式的事后”代码评估,但脚本注入运行速度明显更快。检查一下。基于任意字符串注入脚本标记与使用
eval()
完全相同,至少在应该避免
eval()
的原因方面是如此。@MCL你能在回答中对此进行更多的扩展吗?我可以问你为什么要避免像瘟疫一样的
eval()
然后告诉你,注入任意的
标记也有同样的风险。基本上,当使用这两种方法中的一种时,您所做的事情是相同的:接受任意字符串