46

新しい URL がクロスドメインの場合、IE でwindow.opener開いたウィンドウでは利用できないことがわかりました。IE でウィンドウ オープナーを検出する方法window.open

これは、ウィンドウが自分のドメインで開始され、そこから出て、自分のドメインに戻ってきた場合に発生します。ポップアップでソーシャル サインアップ (Facebook、Google など) を使用しようとしています。完了すると、新しいウィンドウが閉じられ、オープナーがリダイレクトされます。

Soundcloud がこれを実現していることは知っていますが、その方法がわかりません。URL が彼らの URL から Facebook に変わり、その後閉じます。

サードパーティから自分のサイトにリダイレクトした後、これを実行します。

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

ウィンドウが元々私のドメインであり、その後FBにリダイレクトされ、その後私にリダイレクトされたにもかかわらず、IEで警告が表示されます。サイトを開いてPHPからすぐにリダイレクトするので、問題になる可能性があると思いました。しかし、サイトを開いたときwindow.location.href = 'facebookssite.com'でも、戻ったときにまだ文句を言いましたか。

ノート

内の Google、FB などでは、ソーシャル サインアップは機能しませんiframe。セキュリティ上の理由から、彼らはそれらを許可していないと思います。

4

6 に答える 6

48

逆にやってください。メイン(オープナー)ウィンドウから子ポップアップウィンドウの状態を追跡すると、子ウィンドウがいつドメインに戻ったかを簡単に知ることができるため、再び「話す」ことができます。ただし、子ウィンドウを単独で閉じないでください。オープナ ウィンドウに子ウィンドウから結果を取得させ、それを閉じます。

たとえば、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でテスト済み。

于 2013-09-14T17:10:20.223 に答える
16

セキュリティ上の理由により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) 回避策: 親ページでタイマーを使用してclosedopenedWindow

setInterval(function(){
   if (openedWindow.closed){

   }
},1000);

4) 同じド​​メインにいるので、 localStorageを使用する別のソリューション。親ページはイベントを聞くことができます

window.addEventListener("storage", function(event){

}, true);

あなたのopendWindowコード:

var data = {
  type : 'complete',
  destination : '<?= $destination; ?>'
};

if (localStorage){
   localStorage.setItem(JSON.stringify(data));
}
window.close();
于 2013-09-10T06:38:10.640 に答える
1

localStorage または IndexedDB を使用して、同じドメインからのドキュメントを表示しているが相互参照を持たないウィンドウ間で通信します。

高速タイマーでデータをチェックし、別のデータを保存して受信を確認すると、別のウィンドウがそれを見つけて閉じることができます。

要するに、localStorage を使用してコマンドを渡し、ライブラリを使用してこれを実行し、実行後にコマンドを削除して、戻り値をポストすることもできます。

于 2017-12-24T07:26:31.983 に答える