问题描述
一些网站有 IFRAME
机柜的”break out” 的代码,这意味着如果一个页面 A
作为 IFRAME
加载到父页面 P
中,A
中的一些 Javascript 将外部窗口重定向到 A
。
通常这个 Javascript 看起来像这样:
<script type="text/javascript">
if (top.location.href != self.location.href)
top.location.href = self.location.href;
</script>
我的问题是:作为父母页面 P
而不是 A
内页的作者,如何防止 A
做这个 break-out?
附:在我看来,它应该是一个 cross-site 安全违规,但它不是。
最佳解决方案
尝试使用 onbeforeunload 属性,这将允许用户选择是否要离开页面。
示例:https://developer.mozilla.org/en-US/docs/Web/API/Window.onbeforeunload
在 HTML5 中,您可以使用沙盒属性。请参见下面 Pankrat 的答案。 http://www.html5rocks.com/en/tutorials/security/sandboxed-iframes/
次佳解决方案
使用 HTML5 添加了 iframe sandbox 属性。在写这篇 works on Chrome, Safari, Firefox and recent versions of IE and Opera 的时候,几乎要做的就是:
<iframe src="url" sandbox="allow-forms allow-scripts"></iframe>
如果要允许 top-level 重定向指定 sandbox="allow-top-navigation"
。
第三种解决方案
我用 sandbox = “…”
-
allow-forms 允许表单提交
-
allow-popups 允许弹出窗口
-
allow-pointer-lock 允许指针锁定
-
allow-same-origin 允许文档保持其起源
-
allow-scripts 允许 JavaScript 执行,并且还允许功能自动触发
-
allow-top-navigation 允许文档通过浏览 top-level 窗口来突破框架
顶部导航是您想要防止的,所以请留下,不会被允许。任何遗漏的东西都将被阻止
恩。
<iframe sandbox="allow-same-origin allow-scripts allow-popups allow-forms" src="http://www.example.com"</iframe>
第四种方案
阅读 w3.org spec 后。我找到了沙盒属性。
您可以设置 sandbox=""
,阻止 iframe 重定向。话虽如此,它也不会重定向 iframe 。您将基本失去点击。
示例:http://jsfiddle.net/ppkzS/1/没有沙箱的实例:http://jsfiddle.net/ppkzS/
第五种方案
我知道问题已经很久了,但是这里是我的改进版本,只有当 iframe 加载时,它才会等待 500ms 的任何后续调用。
<script type="text/javasript">
var prevent_bust = false ;
var from_loading_204 = false;
var frame_loading = false;
var prevent_bust_timer = 0;
var primer = true;
window.onbeforeunload = function(event) {
prevent_bust = !from_loading_204 && frame_loading;
if(from_loading_204)from_loading_204 = false;
if(prevent_bust){
prevent_bust_timer=500;
}
}
function frameLoad(){
if(!primer){
from_loading_204 = true;
window.top.location = '/?204';
prevent_bust = false;
frame_loading = true;
prevent_bust_timer=1000;
}else{
primer = false;
}
}
setInterval(function() {
if (prevent_bust_timer>0) {
if(prevent_bust){
from_loading_204 = true;
window.top.location = '/?204';
prevent_bust = false;
}else if(prevent_bust_timer == 1){
frame_loading = false;
prevent_bust = false;
from_loading_204 = false;
prevent_bust_timer == 0;
}
}
prevent_bust_timer--;
if(prevent_bust_timer==-100) {
prevent_bust_timer = 0;
}
}, 1);
</script>
和 onload="frameLoad()"
和 onreadystatechange="frameLoad();"
必须添加到框架或 iframe 。
第六种方案
我发现了一些有用的黑客:
Using JS how can I stop child Iframes from redirecting or at least prompt users about the redirect
http://www.codinghorror.com/blog/2009/06/we-done-been-framed.html
http://coderrr.wordpress.com/2009/02/13/preventing-frame-busting-and-click-jacking-ui-redressing/
参考文献
注:本文内容整合自 Google/Baidu/Bing 辅助翻译的英文资料结果。如果您对结果不满意,可以加入我们改善翻译效果:薇晓朵技术论坛。