À l'aide de JS, comment puis-je empêcher Child Iframes de rediriger ou, au moins, d'alerter les utilisateurs sur la redirection

Beaucoup de sites ont des scripts similaires à ceux ci-dessous. Ceux-ci permettent d'empêcher d'autres personnes d'encadrer les sites.

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

J'ai besoin de me rendre compte que l'iframe essaie de rediriger, et si c'est le cas, je supprimerai iFrame et je placerai un lien vers le site. De cette façon, je ne viole pas la politique d'utilisation du site Web encadré et je lierai aussi le site. Je comprends que vous pouvez utiliser l'événement onbeforeunload comme discuté ici et ici, mais les deux semblent vraiment contraire à l'éthique. Je me souviens de lire quelque part sur une bibliothèque qui fait exactement la même chose (digg fait la même chose). Des prospects?

Le problème avec la solution ci-dessus est qu'il peut être supprimé en utilisant un simple:

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

Une fois que cela a été appelé, le prevent_bust ne sera jamais incrémenté, ce qui signifie que le site Web sera prevent_bust librement sans votre consentement ou votre connaissance. Mauvaise affaire.

Si vous vouliez une version fonctionnelle de cette solution, je vous recommande de le faire à la place:

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

Malheureusement, cela cause un seul problème – il est banal de récupérer l'intervalle qui a été défini, de le désactiver, puis de redéfinir la 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/>"; } 

Votre meilleur pari est en fait de résoudre ce problème côté serveur (si vous le pouvez). Si vous avez accès au serveur pour le site Web qui tiendra les iframes, créez un emplacement provisoire, proxy, où vous tirez les données du site Web, puis retirez les étiquettes de 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(); 

Vous utiliserez ensuite la balise:

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

Malheureusement, cela signifie que votre iframe sera exécuté sans JavaScript, qui pourrait paralyser, sinon complètement lobotomiser le site en question. Vous devrez également vous assurer que tous les attributs src sont correctement modifiés pour les nœuds descendants dans le HTML du site étranger.

D'autre part, vous pouvez demander à votre serveur de vérifier le site encadré et toutes ses pages JS pour voir si l'emplacement supérieur de RegExp (. | [\ S * ("| ')) correspond à top.location, top [ "L'emplacement et le haut ['emplacement] existe (ou s'il y a des références au sommet du tout), puis utilisez un lien s'il existe et que le site est correct si ce n'est pas le cas. Le préjudice ici est que vous obligerez l'utilisateur à attendre que le site secondaire soit chargé deux fois – une fois sur le serveur et une fois dans son navigateur. (Sauf si tout est fait par JS, mais cela est généralement plus ennuyeux, à mon avis).

Personnellement, je suis d'avis que la foule «ne pas encadrer mon site» peut généralement gagner la plupart des batailles qui impliquent directement l'iframe. D'autre part, si le code est utilisé pour traiter le code HTML avant d'être ajouté à une page Web, l'autre côté est plus qu'une chance de combattre.

En guise de note, tout cela peut se faire via JavaScript et AJAX, mais cela sera généralement plus lent. Utilisez le serveur, si vous le pouvez.

Si vous utilisez HTML5, je suggérerais d'utiliser la nouvelle propriété "sandbox" MAIS il n'est pas encore compatible avec tous les navigateurs. http://www.w3schools.com/tags/att_iframe_sandbox.asp

Dans mon cas, je viens d'ajouter "allow-forms" et "allow-scripts", car les valeurs de la propriété sandbox et le site intégré ne sont plus redéployés et peuvent encore fonctionner avec JavaScript

En utilisant "allow-top-navigation" car la valeur a redéfini le site.

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

Si quelqu'un connaît des inconvénients à utiliser cette approche, j'aimerais en savoir plus.

Quelqu'un d'autre a la même réponse: https://stackoverflow.com/a/9880360/1404129 (J'ai rencontré cette réponse plus tard)

Vous pouvez essayer de créer un buster buster frame, tout est décrit par Jeff Atwood dans sa publication: Nous avons fait … Encadré! – coddinghorror.com

Bref, vous devez implémenter quelque chose comme ceci:

 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)