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();
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>"; } ?>