通过AJAX以JSON格式返回的动态生成的Javascript在追加时不会执行
我有一个向PHP脚本发出AJAX请求的网页。该PHP脚本使用有效的JSON对象进行响应,并将通过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节点,什么只是文
内容类型
标题设置为应用程序/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()
然后告诉你,注入任意的
标记也有同样的风险。基本上,当使用这两种方法中的一种时,您所做的事情是相同的:接受任意字符串