为啥将 <script> 附加到动态创建的 <iframe> 似乎会在父页面中运行脚本?
Posted
技术标签:
【中文标题】为啥将 <script> 附加到动态创建的 <iframe> 似乎会在父页面中运行脚本?【英文标题】:Why does appending a <script> to a dynamically created <iframe> seem to run the script in the parent page?为什么将 <script> 附加到动态创建的 <iframe> 似乎会在父页面中运行脚本? 【发布时间】:2010-12-08 03:33:16 【问题描述】:我正在尝试使用 javascript 创建一个
不幸的是,我似乎做错了——我的 JavaScript 似乎执行成功,但
这是我正在使用的代码(http://onespot.wsj.com/static/iframe_test.html 的现场演示):
iframe_test.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title><iframe> test</title>
</head>
<body>
<div id="bucket"></div>
<script type="text/javascript" src="http://jqueryjs.googlecode.com/files/jquery-1.3.2.min.js"></script>
<script type="text/javascript">
$(document).ready(function()
$('#bucket').append('<iframe id="test"></iframe>');
setTimeout(function()
var iframe_body = $('#test').contents().find('body');
iframe_body.append('<scr' + 'ipt type="text/javascript" src="http://onespot.wsj.com/static/iframe_test.js"></scr' + 'ipt>');
, 100);
);
</script>
</body>
</html>
iframe_test.js
$(function()
var test = '<p>Shouldn\'t this be inside the <iframe>?</p>';
$('body').append(test);
);
一件看起来不寻常的事情是 iframe_test.js 中的代码甚至可以工作;我没有在
任何想法、建议等将不胜感激!
【问题讨论】:
也许这与 这是为了防止跨站点脚本的设计。如果您可以按照您尝试的方式将脚本注入另一个站点,您可以将脚本从任何 iframe 容器注入到任何网站,而不会出现问题。 好吧,我认为“相同域”规则会阻止向 iframe 中的文档添加任何内容。但是,如果文档来自同一个域,则规则不适用。 @Pointy - 非常感谢您的意见。你的想法听起来可行——我试了一下,但没能成功(尽管这并不意味着它不是一个有效的解决方案)。我最终在下面的答案中使用了代码,这对我的目的来说是一个更优雅的解决方案。 @Nissan Fan - 感谢您的反馈。然而,Pointy 是正确的——因为这个 【参考方案1】:遇到了同样的问题,花了我几个小时才找到解决方案。 您只需要使用 iframe 的文档创建脚本的对象。
var myIframe = document.getElementById("myIframeId");
var script = myIframe.contentWindow.document.createElement("script");
script.type = "text/javascript";
script.src = src;
myIframe.contentWindow.document.body.appendChild(script);
像魅力一样工作!
【讨论】:
太棒了......从几个小时开始就在做同样的事情......现在修好了 @user2284570 有办法跨域吗? @StanJames:不知道,但这通常会导致在没有ᴄᴏʀꜱ的情况下跨 AJAX。 @StanJames 跨域 iframe 是完全不同的球类游戏。即使有解决方案,浏览器也会很快找到它们的路径。这是一项安全功能,可防止坏人破解您的银行密码等。 顺便说一句,为了浏览器的兼容性,我建议将它用于内容窗口:var doc = iframe.contentDocument ? iframe.contentDocument : (iframe.contentWindow ? iframe.contentWindow.document : iframe.document);
【参考方案2】:
我没有找到原始问题的答案,但我确实找到了另一种效果更好的方法(至少对于我的目的而言)。
这不会在父页面上使用 jQuery(这实际上是一件好事,因为我不想在那里加载它),但它确实在
代码:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>frame</title>
</head>
<body>
<div id="test"></div>
<script type="text/javascript">
// create a new <iframe> element
var iframe = document.createElement('iframe');
// append the new element to the <div id="bucket"></div>
var bucket = document.getElementById('test');
bucket.appendChild(iframe);
// create a string to use as a new document object
var val = '<scr' + 'ipt type="text/javascript" src="http://jqueryjs.googlecode.com/files/jquery-1.3.2.min.js"></scr' + 'ipt>';
val += '<scr' + 'ipt type="text/javascript"> $(function() $("body").append("<h1>It works!</h1>"); ); </scr' + 'ipt>';
// get a handle on the <iframe>d document (in a cross-browser way)
var doc = iframe.contentWindow || iframe.contentDocument;
if (doc.document)
doc = doc.document;
// open, write content to, and close the document
doc.open();
doc.write(val);
doc.close();
</script>
</body>
</html>
我希望这对以后的人有所帮助!
【讨论】:
这正是我正在寻找的。有什么办法可以追加到 iframe 中,这样正文内容就不会被删除? 为什么直接写'<scr' + 'ipt
而不是'<script
?
@user2284570:浏览器会按字面意思解释内联 <script>
标签中的任何 HTML 字符串,因此像 var endScript = '</script>';
这样的东西会被解释为当前脚本的过早结束标签,从而导致语法错误。
在 iframe 中粘贴包含 script 标签的整个 html 内容时非常有用
但这有一个缺点,因为doc.write
仅在整个页面加载时才开始写入。【参考方案3】:
原始问题的答案很简单 - 脚本的执行是由 jquery 完成的,并且由于 jquery 加载在顶部框架中,因此无论您将脚本附加到何处,这也是脚本运行的地方。毫无疑问,jquery 的更智能实现可以使用正确的窗口对象,但现在情况就是这样。
至于解决方法,您已经有了两个很好的答案(即使一个是您自己的)。我可能要补充的是,您可以使用其中一种解决方法将 jquery.js 包含在 iframe 中,然后获取该 jquery 对象而不是顶部对象来插入您的附加标记......但这也可能是矫枉过正。
【讨论】:
以上是关于为啥将 <script> 附加到动态创建的 <iframe> 似乎会在父页面中运行脚本?的主要内容,如果未能解决你的问题,请参考以下文章