Ответ 1
Проблема с вышеупомянутым решением заключается в том, что его можно удалить с помощью простого:
if( top != self )
delete top.onbeforeunload;
Как только это вызвано, тогда prevent_bust
никогда не будет увеличиваться, и это означает, что веб-сайт будет свободно перенаправлен без вашего согласия или знания. Плохая сделка.
Если вы хотите последовательно работать с этим решением, я бы рекомендовал сделать это вместо этого:
// 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 );
К сожалению, это приводит к одной проблеме - тривиально извлекать интервал, который был установлен, отключить его, а затем перенаправить страницу:
// 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, создайте промежуточное место прокси-сервера, где вы вытащите данные веб-сайта, а затем разделите теги script:
// 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, который может испортить, если не полностью лоботомизировать данный веб-сайт. Вам также необходимо убедиться, что все атрибуты src правильно изменены для узлов-потомков в HTML-сайте иностранного сайта.
С другой стороны, вы можете проверить свой серверный сайт и все его страницы JS, чтобы узнать, находится ли местоположение RegExp top (. | [\ s * ( "| ')) (это будет соответствовать top.location, top [" location и top ['location) существует (или если есть какие-либо ссылки на верхнюю часть), а затем используйте ссылку, если она существует, и собственно сайт, если это не так. Ущерб здесь заключается в том, что тогда вы вынуждаете пользователя ждать, пока вторичный сайт будет загружаться дважды - один раз на сервере и один раз в своем браузере. (если все не сделано через JS, но, на мой взгляд, это, как правило, более раздражает).
Лично я придерживаюсь мнения, что толпа "не кадрирует мой сайт" обычно может выиграть большинство битв, которая напрямую связана с iframe. С другой стороны, если код используется для обработки HTML, прежде чем он будет добавлен к веб-странице, тогда другая сторона будет больше, чем шанс для боя.
В качестве побочного примечания все это можно выполнить с помощью JavaScript и AJAX, но это, как правило, будет немного медленнее. Используйте сервер, если можете.