2009-11-25 6 views
14

Molti siti hanno script simili a quello riportato di seguito. Questi sono posti per impedire ad altre persone di inquadrare i siti.Utilizzo di JS come posso interrompere l'iframe figlio dal reindirizzamento o almeno richiedere agli utenti il ​​reindirizzamento

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

ho bisogno di qualche modo per rendersi conto che l'iframe sta cercando di reindirizzare e se lo è, io toglierò l'iFrame e invece inserire un link al sito. In questo modo, non violento la politica di utilizzo del sito web incorniciato e anche il link al sito. Capisco che puoi utilizzare l'evento onbeforeunload come discusso here e here ma entrambi sembrano non etici. Ricordo di aver letto da qualche parte su una libreria che fa esattamente la stessa cosa (digg fa la stessa cosa). Qualche vantaggio?

risposta

16

Il problema con il sopra soluzione è che può essere rimosso mediante un semplice:

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

una volta che è stato chiamato, allora il prevent_bust sarà n mai essere incrementato, e ciò significa che il sito web sarà liberamente reindirizzato senza il tuo consenso o conoscenza. Cattivo affare

Se si voleva una versione costantemente funzionale di questa soluzione, mi sento di raccomandare di fare questo, invece:

// 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); 

Purtroppo, questo provoca lasciare un problema - è una cosa banale per recuperare l'intervallo che ha stato impostato, non impostato, e quindi la pagina reindirizzare:

// 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/>"; 
} 

la cosa migliore è in realtà per risolvere questo problema di server lato (se potete). Se si ha accesso al server per il sito web che conterrà iframe, creare un interim, posizione procura in cui si tira nei dati del sito e quindi a nudo i tag di 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(); 

Si potrebbe quindi utilizzare il tag:

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

Sfortunatamente, ciò significa che l'iframe verrà eseguito senza JavaScript che potrebbe paralizzare, se non completamente, lobotomizzare il sito Web in questione. Dovrai anche assicurarti che tutti gli attributi src siano correttamente modificati per i nodi discendenti nel codice HTML del sito straniero.

D'altra parte, è possibile che il server controlli il sito con frame e tutte le relative pagine JS per vedere se la posizione superiore di RegExp (. | [\ S * ("| ')) (corrisponde alla parte superiore. location, top ["location, and top ['location] esiste (o se ci sono riferimenti a top in assoluto), e quindi usa un link se esiste e il sito corretto se non lo è. Il danno è che quindi stai costringendo l'utente ad aspettare che il sito secondario si carichi due volte, una volta sul server e una volta nel browser. (a meno che tutto venga fatto tramite JS, ma a mio avviso è generalmente più fastidioso).

Personalmente, sono dell'opinione che la folla "non inquadrare il mio sito" possa generalmente vincere la maggior parte delle battaglie che coinvolgono direttamente l'iframe.D'altra parte, se il codice viene utilizzato per elaborare l'HTML prima di essere aggiunto a una pagina Web, l'altra faccia è più di una possibilità di combattimento.



Come nota laterale, tutti questi può essere realizzato tramite JavaScript e AJAX, ma sarà generalmente un po 'più lento. Usa il server, se puoi.

+1

La prima opzione sembra buona. C'è un problema però, un refresh premuto sul browser attiverà il gestore window.onbeforeunload ed eseguirà esattamente la stessa azione definita nella funzione. Inoltre, qualsiasi azione sul sito, come una richiesta di pagina o un invio di un modulo, non viene eseguita mentre il gestore viene richiamato di nuovo. La soluzione per questo sarebbe un po 'doloroso "Aggiungi pre-invio/navigazione javascript per annullare le azioni dallo script frame buster. –

+0

Questo non impedisce a qualcuno di usare' .. ' – Andrew

3

si può provare a creare cornice Buster Buster, tutto è descritto da Jeff Atwood nel suo post sul blog: We Done Been ... Framed! - coddinghorror.com

In breve, è necessario implementare qualcosa di simile:

var prevent_bust = 0 
window.onbeforeunload = function() { prevent_bust++ } 
setInterval(function() { 
    if (prevent_bust > 0) { 
    prevent_bust -= 2 
    window.top.location = 'http://server-which-responds-with-204.com' 
    // replace your iframe with link to it 
    } 
}, 1) 
+0

Sembra a posto. Dovrà scrivere un po 'di più per eseguire tutte le altre azioni. Grazie!! –

6

Se si utilizza HTML5, suggerisco di utilizzare la nuova proprietà "sandbox", ma non è ancora compatibile con tutti i browser. http://www.w3schools.com/tags/att_iframe_sandbox.asp

Nel mio caso ho appena aggiunto "allow-forme" e "permettere-script", come i valori delle proprietà sandbox e la site non è più reindirizzare e ancora in grado di eseguire JavaScript

utilizzando "allow-top-navigazione "come valore ha fatto di nuovo il reindirizzamento del sito!

es: <iframe sandbox="allow-forms allow-scripts" ... /></iframe>

Se qualcuno sa qualsiasi Contro di utilizzare questo approccio mi piacerebbe sapere a questo proposito.

qualcun altro con stessa risposta: https://stackoverflow.com/a/9880360/1404129 (Mi sono imbattuto in questa risposta più tardi)

Problemi correlati