Comment puis-je contourner la sécurité entre domaines window.opener

Je viens de découvrir que window.opener n'est pas disponible dans une fenêtre ouverte via window.open si la nouvelle URL est window.open , dans IE. Comment puis-je détecter l'ouverture des fenêtres dans IE

Cela se produira si la fenêtre commence dans mon domaine, la laisse et revient à mon domaine. Je tente d'avoir une inscription sociale (Facebook, google, etc.) dans la fenêtre contextuelle. Une fois qu'il est terminé, fermez la nouvelle fenêtre et redirigez l'ouvreur.

Je sais que Soundcloud retient ce problème, mais je n'ai aucune idée de comment. Je vois le changement d'URL de leur part vers Facebook, puis ferme.

Après avoir redirigé vers mon site depuis le tiers, je l'exécute:

 var data = { type : 'complete', destination : '<?= $destination; ?>' }; if ( window.opener ) { window.opener.postMessage( JSON.stringify( data ), '*' ); window.close(); } else { alert( "Unable to find window" ); } 

Il s'annonce dans IE, même si la fenêtre était à l'origine mon domaine, qui a ensuite été redirigé vers FB, puis redirigé vers moi. Je pensais que je pourrais depuis que j'ouvre mon site et que je redirige immédiatement depuis PHP. Cependant, même lorsque j'ai ouvert mon site, window.location.href = 'facebookssite.com' encore plaint lors du retour.

REMARQUE

Les inscriptions sociales ne fonctionnent pas pour Google, FB, etc. dans un iframe . Je crois qu'ils ne les autorisent pas pour des raisons de sécurité.

Faites-le en sens inverse. Suivez l'état de la fenêtre popup enfant de la fenêtre principale (ouvreur), et vous pouvez facilement savoir quand la fenêtre enfant a été parcourue dans votre domaine afin que vous puissiez "parler" à nouveau. Mais ne fermez pas la fenêtre enfant par elle-même. Laissez la fenêtre d'ouverture obtenir le résultat de la fenêtre enfant, puis fermez-la.

Par exemple, main.html :

 <!DOCTYPE html> <head> <title>main</title> <meta http-equiv="X-UA-Compatible" content="IE=edge"/> <script> window.addEventListener("message", function(ev) { if (ev.data.message === "deliverResult") { alert("result: " + ev.data.result); ev.source.close(); } }); function Go() { var child = window.open("child.html", "_blank", "height=200,width=200"); var leftDomain = false; var interval = setInterval(function() { try { if (child.document.domain === document.domain) { if (leftDomain && child.document.readyState === "complete") { // we're here when the child window returned to our domain clearInterval(interval); alert("returned: " + child.document.URL); child.postMessage({ message: "requestResult" }, "*"); } } else { // this code should never be reached, // as the x-site security check throws // but just in case leftDomain = true; } } catch(e) { // we're here when the child window has been navigated away or closed if (child.closed) { clearInterval(interval); alert("closed"); return; } // navigated to another domain leftDomain = true; } }, 500); } </script> </head> <body> <button onclick="Go()">Go</button> </body> 

Child.html :

 <!DOCTYPE html> <head> <title>child</title> <meta http-equiv="X-UA-Compatible" content="IE=edge"/> <script> window.addEventListener("message", function(ev) { if (ev.data.message === "requestResult") { // ev.source is the opener ev.source.postMessage({ message: "deliverResult", result: true }, "*"); } }); </script> </head> <body> <a href="http://www.example.com">Go to example.com</a> Then click the browser Back button when ready. </body> 

Testé avec IE10.

En raison de la raison de sécurité, window.opener est supprimé lors de la redirection vers un domaine différent. Le navigateur ne se window.opener pas de restaurer window.opener lorsque vous êtes de retour. Dans votre cas, vous pouvez essayer:

1) Faites votre authentification dans un iframe si possible au lieu d'utiliser la redirection.

2) Dans votre cas, je vois que vous devez publier les données dans la fenêtre parentale. Vous pourriez essayer cela à la place:

Dans votre fenêtre ouverte, enregistrez vos data et fermez normalement.

 var data = { type : 'complete', destination : '<?= $destination; ?>' }; window.hasData = true; window.data = data; window.close(); 

Votre fenêtre parent a accès à votre fenêtre ouverte et peut gérer son événement close :

 openedWindow.beforeunload = function (){ //here you could access this.data or openedWindow.data because you're on the same domain if (this.hasData){ } //Reason we have this check is because the beforeunload event fires whenever the user leaves your page for any reason including close, submit, clicking a link, ... } 

3) Une solution de contournement: utilisez une minuterie dans votre page parent pour vérifier la propriété closed de la openedWindow

 setInterval(function(){ if (openedWindow.closed){ } },1000); 

4) Une autre solution utilisant localStorage que vous êtes sur le même domaine. Votre page parent peut écouter l'événement

 window.addEventListener("storage", function(event){ }, true); 

Votre code openWindow:

 var data = { type : 'complete', destination : '<?= $destination; ?>' }; if (localStorage){ localStorage.setItem(JSON.stringify(data)); } window.close(); 
  1. De votre iframe, page Web, sur yoursite.com … ouvrez une nouvelle fenêtre sur votre site.com
  2. La fenêtre se redirige vers Google, Twitter, quoi que ce soit
  3. Une fois terminé, la redirection OAuth renvoie la fenêtre vers une page sur votre site.com
  4. La nouvelle fenêtre, car elle a la même origine que la page qui l'a ouverte, peut communiquer via window.open

Dans ma société, nous avons différents domaines et il y a le cas où le site de l'intranet doit obtenir notre site public (pour finalement se débarrasser de la maintenance des données dupliquées). Inspiré dans Ben Vinegar, je suis venu à cette solution solution simple en évitant:

Appel vers le site Web du domaine (dans mon cas avec le même nom que l'externe)

Local ' getInfo.php '

 <?php $idSp = (isset($_GET['idSp'])?$_GET['idSp']:null); echo file_get_contents('http://192.168.1.10/folder/getInfo.php?idSp='.$idSp); ?> 

Retour externe ' getInfo.php '

  <?php echo '<script>window.opener.manageDisplay('.$getRes.','.$isOK.');</script>'; if($auto_close){ echo "<script>window.close();</script>"; } ?>