Javascript 关闭 iframe 跨域
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2182027/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Close iframe cross domain
提问by HP.
I am trying to do something similar to the Clipper application here http://www.polyvore.com/cgi/clipper
我正在尝试做一些类似于这里的 Clipper 应用程序http://www.polyvore.com/cgi/clipper
I can make the iframe appear in another website (cross domain). But I cannot make the "close" button to work.
我可以让 iframe 出现在另一个网站(跨域)中。但是我无法使“关闭”按钮起作用。
This is what I used but it doesn't work for cross domain (basically remove the iframe element)
这是我使用的,但它不适用于跨域(基本上删除 iframe 元素)
window.parent.document.getElementById('someId').parentNode.removeChild(window.parent.document.getElementById('someId'));
Can you help? Thanks.
你能帮我吗?谢谢。
回答by Matthew Flaschen
You should use a library that abstracts this (e.g. http://easyxdm.net/wp/, not tested). Fragment ID messaging may not work in all browsers, and there are better approaches, such as postMessage.
您应该使用一个抽象的库(例如http://easyxdm.net/wp/,未经测试)。Fragment ID 消息传递可能不适用于所有浏览器,有更好的方法,例如postMessage。
However, your example (Clipper) is using a hack called fragment id messaging. This can be cross-browser, provided the page containing your iframe is the top level. In other words, there are a total of two levels. Basically, the child sets the fragment of the parent, and the parent watches for this.
但是,您的示例(Clipper)正在使用一种称为fragment id messages的黑客。这可以是跨浏览器的,前提是包含 iframe 的页面是顶级页面。也就是说,一共有两个层次。基本上,孩子设置了父母的片段,父母会注意这一点。
This is a similar approach to Clipper's:
这是与 Clipper 类似的方法:
parent.html
父.html
<html>
<head>
<script type="text/javascript">
function checkForClose()
{
if(window.location.hash == "#close_child")
{
var someIframe = document.getElementById("someId");
someIframe.parentNode.removeChild(someIframe);
}
else
{
setTimeout(checkForClose, 1000)
}
}
setTimeout(checkForClose, 1000);
</script>
</head>
<body>
<iframe name="someId" id="someId" src="child.html" height="800" width="600">foo</iframe>
</body>
</html>
child.html:
child.html:
<html>
<head>
<script type="text/javascript">
setTimeout(function(){window.parent.location.hash = "close_child";}, 5000);
</script>
<body style="background-color: blue"></body>
</html>
EDIT2: Cross-domain and independently controlled are different. I dug into the (heavily minified/obfuscated) Polyvore code to see how it works (incidentally, it doesn't in Firefox). First remember that bookmarklets, such as the Clipper, live in the context of the page open when they start. In this case, the bookmarklet loads a script, which in turn runs an init function which generates an iframe, but also runs:
EDIT2:跨域和独立控制是不同的。我深入研究了(严重缩小/混淆的)Polyvore 代码以了解它是如何工作的(顺便说一句,它不在 Firefox 中)。首先请记住,书签(例如 Clipper)在它们启动时处于打开页面的上下文中。在这种情况下,书签加载了一个 script,它依次运行一个生成iframe的 init 函数,但也运行:
Event.addListener(Event.XFRAME, "done", cancel);
If you digg into addListener, you'll find (beautified):
如果你深入研究 addListener,你会发现(beautified):
if (_1ce2 == Event.XFRAME) {
if (!_1cb3) {
_1cb3 = new Monitor(function () {
return window.location.hash;
},
100);
Event.addListener(_1cb3, "change", onHashChange);
}
}
cancel includes:
取消包括:
removeNode(iframe);
Now, the only remaining piece is that the iframe pageloads another scriptwith a ClipperForm.init function that includes:
现在,唯一剩下的部分是iframe 页面加载另一个带有 ClipperForm.init 函数的脚本,其中包括:
Event.addListener($("close"), "click", function () {
Event.postMessage(window.parent, _228d, "done");
});
So we see clearly they are using fragment ID messaging.
所以我们清楚地看到他们正在使用片段 ID 消息传递。
回答by Bruce
Try hiding the contents of the iframe, and don't worry about actually getting rid of the iframe element in the parent.
尝试隐藏 iframe 的内容,而不必担心实际上摆脱父级中的 iframe 元素。
回答by Kyle
There is another implementation of the old hash hack. It's backwards compatible, easy javascript-only, and very easy to implement:
旧的哈希黑客还有另一种实现。它向后兼容,简单的 javascript-only,并且非常容易实现:
http://www.onlineaspect.com/2010/01/15/backwards-compatible-postmessage/
http://www.onlineaspect.com/2010/01/15/backwards-compatible-postmessage/

