我刚刚发现,如果新网址是跨域的IE,则window.opener
在通过window.open
打开的窗口中不可用。 How do I detect window opener in IE
如果窗口在我的域中启动,离开它,然后返回到我的域,则会发生这种情况。我试图在弹出窗口中进行社交注册(facebook,google等)。完成后,它应该关闭新窗口并重定向开启器。
我知道Soundcloud正在关闭它,但我不知道如何。我看到网址从他们改为Facebook,然后关闭。
从第三方重定向回我的网站后,我运行:
var data = {
type : 'complete',
destination : '<?= $destination; ?>'
};
if ( window.opener ) {
window.opener.postMessage( JSON.stringify( data ), '*' );
window.close();
}
else {
alert( "Unable to find window" );
}
它在IE中提醒,即使窗口最初是我的域,然后重定向到FB,然后重定向回到我。我想可能因为我打开我的网站并立即从PHP重定向可能是一个问题。然而,即使我打开我的网站,window.location.href = 'facebookssite.com'
它仍然在返回时抱怨。
注意
社交注册不适用于iframe
内的Google,FB等。我相信他们出于安全原因不允许他们。
答案 0 :(得分:32)
反过来做。从主(开启者)窗口跟踪子弹出窗口的状态,您可以很容易地知道子窗口何时被导航回您的域,因此您可以再次与其“对话”。但是不要单独关闭子窗口。让开启窗口从子窗口获取结果,然后关闭它。
例如, 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>
使用IE10测试。
答案 1 :(得分:10)
出于安全原因,重定向到其他域时会删除window.opener
。当你回来时,浏览器无需恢复window.opener
。在您的情况下,您可以尝试:
1)如果可能,请在iframe中进行身份验证,而不是使用重定向。
2)在您的情况下,我发现您需要将数据发布回父窗口。你可以试试这个:
在您打开的窗口中,只需存储data
并正常关闭。
var data = {
type : 'complete',
destination : '<?= $destination; ?>'
};
window.hasData = true;
window.data = data;
window.close();
您的父窗口可以访问您打开的窗口,并可以处理其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)解决方法:在父页面中使用计时器检查closed
openedWindow
属性
setInterval(function(){
if (openedWindow.closed){
}
},1000);
4)使用localStorage的另一种解决方案,因为您在同一个域中。您的父页面可以收听事件
window.addEventListener("storage", function(event){
}, true);
您的opensWindow代码:
var data = {
type : 'complete',
destination : '<?= $destination; ?>'
};
if (localStorage){
localStorage.setItem(JSON.stringify(data));
}
window.close();
答案 2 :(得分:1)
答案 3 :(得分:1)
使用localStorage或IndexedDB在显示来自同一域但不具有彼此引用的文档的窗口之间进行通信。
只需要一个高速计时器检查数据,保存另一个数据以确认收到,另一个窗口可以找到并关闭。
简而言之 - 您使用localStorage传递命令,甚至可以使用库来执行此操作并在执行后删除命令,并发布返回值。
答案 4 :(得分:0)
您可以使用为此情况提供的use window.postMessage()
。
说明:https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage
答案 5 :(得分:-1)
在我的公司,我们有不同的域名,并且内部网站点必须获取我们的公共网站(最终摆脱重复数据的维护)。 灵感来自Ben Vinegar,我来到这个解决方案简单的解决方案,避免:
调用域名网页(在我的情况下,与外部网页同名)
本地' getInfo.php '
<?php
$idSp = (isset($_GET['idSp'])?$_GET['idSp']:null);
echo file_get_contents('http://192.168.1.10/folder/getInfo.php?idSp='.$idSp);
?>
外部' getInfo.php '返回
<?php
echo '<script>window.opener.manageDisplay('.$getRes.','.$isOK.');</script>';
if($auto_close){ echo "<script>window.close();</script>"; }
?>