关于javascript:如何防止IFRAME重定向顶级窗口

How to prevent IFRAME from redirecting top-level window

某些网站具有用于"破解" IFRAME附件的代码,这意味着,如果将页面A作为IFRAME加载到父页面P中,则A中的某些Javascript将外部窗口重定向到

通常,此Javascript如下所示:

1
2
3
<script type="text/javascript">
  if (top.location.href != self.location.href)
     top.location.href = self.location.href;

我的问题是:作为父页面P的作者而不是内部页面A的作者,如何防止A进行此突破?

附言 在我看来,这应该是跨站点安全性违规,但事实并非如此。


使用HTML5,添加了iframe沙箱属性。在撰写本文时,此功能可在Chrome,Safari,Firefox和IE和Opera的最新版本上运行,但几乎可以满足您的要求:

1
<iframe src="url" sandbox="allow-forms allow-scripts"></iframe>

如果要允许顶级重定向,请指定sandbox="allow-top-navigation"


我使用沙箱=" ..."

  • allow-forms允许表单提交
  • allow-popups允许弹出窗口
  • allow-pointer-lock允许指针锁定
  • allow-same-origin允许文档保持其原点
  • allow-scripts允许JavaScript执行,还允许功能自动触发
  • allow-top-navigation允许通过浏览顶层窗口使文档脱离框架

顶部导航是您要防止的,因此将其省略,将不被允许。任何遗漏的东西都会被阻止

例如

1
        <iframe sandbox="allow-same-origin allow-scripts allow-popups allow-forms" src="http://www.example.com"</iframe>


尝试使用onbeforeunload属性,该属性将使用户选择是否要离开页面。

示例:https://developer.mozilla.org/en-US/docs/Web/API/Window.onbeforeunload

在HTML5中,您可以使用沙盒属性。请参阅下面的Pankrat答案。
http://www.html5rocks.com/zh-CN/tutorials/security/sandboxed-iframes/


阅读w3.org规范之后。我找到了沙箱属性。

您可以设置sandbox="",以防止iframe重定向。话虽如此,它也不会重定向iframe。您将基本上失去点击。

此处的示例:http://jsfiddle.net/ppkzS/1/
没有沙箱的示例:http://jsfiddle.net/ppkzS/


我知道问题已经解决很久了,但是这是我的改进版本,只有在加载iframe时,它将等待500ms进行后续调用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
<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);

onload="frameLoad()"onreadystatechange="frameLoad();"必须添加到框架或iframe。


我发现了一些有用的技巧:

使用JS如何停止子iframe重定向或至少提示用户有关重定向的信息

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/


在我的情况下,我希望用户访问内部页面,以便服务器将其IP视为访问者。如果我使用php代理技术,我认为内页会将我的服务器IP视为访问者,因此效果不佳。到目前为止,我得到的唯一解决方案是onbeforeunload。
把它放在你的页面上:

1
2
3
4
<script type="text/javascript">
    window.onbeforeunload = function () {                      
         return"This will end your session";
    }

这既在Firefox中工作,也就是我测试过的东西。
您会发现使用evt.return(what)废话之类的版本...在Firefox中不起作用。


由于您在iframe中加载的页面可以使用setInterval执行"突破"代码,因此onbeforeunload可能不那么实际,因为它可能会向用户显示"您确定要离开吗?"对话。

还有iframe安全属性,该属性仅适用于IE和Opera

:(


这样,您将能够控制框架页面的任何操作,而这是您无法控制的。相同域来源策略适用。