使用 JS 如何阻止子 Iframe 重定向或至少提示用户重定向 [英] Using JS how can I stop child Iframes from redirecting or at least prompt users about the redirect

查看:60
本文介绍了使用 JS 如何阻止子 Iframe 重定向或至少提示用户重定向的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

许多站点都有类似于下面的脚本.这些是为了阻止其他人框架网站.

Many sites have scripts similar to the one below. These are put to stop other people from framing the sites.

if (top.location != location) {
  top.location.href = document.location.href;
}

我需要某种方式来意识到 iframe 正在尝试重定向,如果是,我将删除 iFrame 并放置指向该站点的链接.这样,我不会违反框架网站的使用政策,也不会链接到该网站.我知道您可以使用 此处 中讨论的 onbeforeunload 事件和这里 但两者似乎都非常不道德.我记得在某处读到过一个关于做完全相同事情的图书馆(digg 做同样的事情).任何线索?

I need some way to realize that the iframe is trying to redirect, and if it is , I will remove the iFrame and instead place a link to the site. This way, I don't violate the usage policy of the framed website and also link to the site. I understand you can use the onbeforeunload event as discussed here and here but both seem really unethical. I remember reading somewhere about a library that does the exact same thing (digg does the same thing). Any leads?

推荐答案

上述解决方案的问题是可以使用简单的方法将其删除:

The problem with the above solution is that it can be removed using a simple:

if( top != self )
    delete top.onbeforeunload;

一旦被调用,prevent_bust 将永远不会增加,这意味着网站将在未经您同意或不知情的情况下自由重定向.糟糕的交易.

Once that has been called, then the prevent_bust will never be incremented, and that means that the website will be freely re-directed without your consent or knowledge. Bad deal.

如果您想要该解决方案的一致功能版本,我建议您改为这样做:

If you wanted a consistently functional version of that solution, I would recommend doing this instead:

// Create a random seed value, making it almost impossible to 
// determine what is being tested for.
var prevent_bust = Math.random() * 3000; 

// enclose everything in a function, so that it cannot be addressed
function iniFunc ( init ) { 
    // The function is no longer in scope of the main window.
    function onbeforeunload() { prevent_bust++ }
    window.onbeforeunload = onbeforeunload;
    setInterval( function() {
        // make sure the function was not deleted.
        if( window.onbeforeunload != onbeforeunload )
        {
            prevent_bust = init + 1;
            window.onbeforeunload = onbeforeunload;
        }
        if (prevent_bust > init ) {  // All comparison is to the random seed.
            prevent_bust -= 2
            window.top.location = 'http://server-which-responds-with-204.com/' 
            // Unfortunately, you have absolutely no idea which website caused
            // the incrementation, so you cannot replace it with a link!
            //
            // You might try to simply ignore it and just use the iframe as is -- 
            // theoretically, they are no longer able to bust this frame. 
            // (this theory will be disproved below).
       }
   }, 1 );
};
iniFunc( prevent_bust );

不幸的是,这确实会导致一个问题——检索已设置的间隔,取消设置,然后重定向页面是一件微不足道的事情:

Unfortunately, this does cause leave one problem -- it is a trivial thing to retrieve the interval which has been set, unset it, and then re-direct the page:

// setTimeout will return the highest timeout which is not "in use", in this case,
// it will be the original setInterval (from the above function) + 1.
// Event if there are 1,000 intervals already set, it will be rather trivial to 
// clear them all.
var currentInterval = 10000;
// window.setTimeout( gotoHREF, 100 );

// clearInterval will not interfere with setTimeout, so we can clear all
// of the Intervals already set.
for( var i = 0; i < currentInterval; i++ ) top.clearInterval( i );

function gotoHREF(){
    top.location.href = "http://<my-url/>";
}

实际上,您最好的办法是在服务器端解决这个问题(如果可以的话).如果您有权访问将保存 iframe 的网站服务器,请创建一个临时代理位置,您可以在其中提取网站数据,然后去除脚本标签:

Your best bet is actually to solve this issue server side (if you can). If you have access to the server for the website which will hold iframes, create an interim, proxy location where you pull in the website's data and then strip the script tags:

// In php
$dd = new DOMDocument();
// file_get_contents will simply convert the entire web address into a String
$dd->loadXML( file_get_contents( "http://" . $_GET[ 'loadedURL' ] ) );
$scripts = $dd->getElementsByTagName( "script" );

// iterate through the website and remove all script tags.
for( $i = 0; $i < $scripts->length; $i++ )
{
    $current = $scripts->item( $i );
    $current->parentNode->removeChild( $current );
}

// output it to the dummy page.
echo $dd->saveXML();

然后您将使用该标签:

<iframe src="redirect.php?loadedURL=http://www.google.com"></iframe>

不幸的是,这意味着您的 iframe 将在没有 JavaScript 的情况下运行,这可能会瘫痪,如果不是完全对相关网站进行脑叶切除.您还需要确保为外部站点的 HTML 中的后代节点正确修改了所有 src 属性.

Unfortunately, this will mean that your iframe will be running without JavaScript which might cripple, if not completely lobotomize the website in question. You'll also need to make sure that all of the src attributes are correctly modified for descendant nodes in the foreign site's HTML.

另一方面,您可以让您的服务器检查框架站点及其所有 JS 页面,以查看 RegExp top(.|[s*("|')) 位置(这将匹配 top.location, top["location, and top[ 'location) 存在(或者如果有任何对 top 的引用),然后使用链接(如果存在),如果不存在则使用正确的站点.这里的不利之处在于,您将迫使用户等待辅助站点加载两次——一次在服务器上,一次在他们的浏览器中.(除非一切都通过 JS 完成,但在我看来,这通常更烦人).

On the other hand, you could have your server check the framed site and all of its JS pages to see if the RegExp top(.|[s*("|'))location (this will match top.location, top["location, and top[ 'location) exists (or if there are any references to top at all), and then use a link if it does exist and the site proper if it does not. The detriment here is that then you are forcing the user to wait for the secondary site to load twice -- once on the server and once in their browser. (unless everything is done through JS, but that is generally more annoying, in my opinion).

就我个人而言,我认为不要框架我的网站"人群通常可以赢得大多数直接涉及 iframe 的战斗.另一方面,如果在将 HTML 附加到网页之前使用代码来处理 HTML,那么另一方就不仅仅是一个战斗机会.



附带说明一下,所有这些都可以通过 JavaScript 和 AJAX 来完成,但这通常会慢一点.如果可以,请使用服务器.

Personally, I'm of the opinion that the "don't frame my site" crowd can generally win most battles which involves the iframe directly. On the other hand, if code is used to process the HTML before it is appended to a web page, then the other side stands more than a fighting chance.



As a side note, all of these can be accomplished through JavaScript and AJAX, but that will generally be a bit slower. Use the server, if you can.

这篇关于使用 JS 如何阻止子 Iframe 重定向或至少提示用户重定向的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆