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

查看:557
本文介绍了使用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顶部(。| [\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,那么另一方不仅仅是战斗机会。





$ b作为旁注,所有这些都可以通过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天全站免登陆