Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/445.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/.htaccess/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何绕过window.opener跨域安全性_Javascript_Cross Domain - Fatal编程技术网

Javascript 如何绕过window.opener跨域安全性

Javascript 如何绕过window.opener跨域安全性,javascript,cross-domain,Javascript,Cross Domain,我刚刚发现window.opener在通过window打开的窗口中不可用。如果新URL是跨域的,请在IE中打开 如果窗口在我的域中启动,离开,然后返回到我的域,就会发生这种情况。我正试图在弹出窗口中注册一个社交网站(facebook、google等)。当它完成时,它应该关闭新窗口并重定向打开程序 我知道Soundcloud正在实现这一点,但我不知道如何实现。我看到URL从他们的更改为Facebook,然后关闭 从第三方重定向回我的站点后,我运行以下操作: var data = { type

我刚刚发现
window.opener在通过
window打开的窗口中不可用。如果新URL是跨域的,请在IE中打开

如果窗口在我的域中启动,离开,然后返回到我的域,就会发生这种情况。我正试图在弹出窗口中注册一个社交网站(facebook、google等)。当它完成时,它应该关闭新窗口并重定向打开程序

我知道Soundcloud正在实现这一点,但我不知道如何实现。我看到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" );
}
var数据={
键入:“完成”,
目标:“”
};
如果(窗口打开器){
window.opener.postMessage(JSON.stringify(数据),'*');
window.close();
}
否则{
警报(“无法找到窗口”);
}
它在IE中发出警报,即使窗口最初是我的域,然后重定向到FB,再重定向回我。我想可能是因为我打开了我的网站,并立即从PHP重定向,这可能是一个问题。然而,即使当我打开我的网站时,
window.location.href='facebooksite.com'
它返回时仍然抱怨

注意

社交注册不适用于
iframe
中的谷歌、FB等。我认为出于安全原因,他们不允许这样做

  • 从yoursite.com上的iframe网页。。。在yoursite.com上打开一个新窗口
  • 该窗口将自己重定向到谷歌、推特等网站
  • 完成后,OAuth重定向将窗口返回到yoursite.com上的页面
  • 新窗口与打开它的页面具有相同的来源,因此可以通过window.open进行通信

  • 由于安全原因,重定向到其他域时,
    window.opener
    将被删除。当您回来时,浏览器不必费心恢复
    窗口。opener
    。在您的情况下,您可以尝试:

    1) 如果可能的话,在iframe中进行身份验证,而不是使用重定向

    2) 在您的情况下,我发现您需要将数据发布回父窗口。您可以尝试以下方法:

    在打开的窗口中,只需存储
    数据
    并正常关闭即可

    var data = {
      type : 'complete',
      destination : '<?= $destination; ?>'
    };
    
    window.hasData = true;
    window.data = data;
    window.close();
    
    3) 解决方法:在父页面中使用计时器检查
    openedWindow的
    closed
    属性

    setInterval(function(){
       if (openedWindow.closed){
    
       }
    },1000);
    
    4) 另一个解决方案使用,因为您在同一个域上。您的父页面可以侦听事件

    window.addEventListener("storage", function(event){
    
    }, true);
    
    您的开放式代码:

    var data = {
      type : 'complete',
      destination : '<?= $destination; ?>'
    };
    
    if (localStorage){
       localStorage.setItem(JSON.stringify(data));
    }
    window.close();
    
    var数据={
    键入:“完成”,
    目标:“”
    };
    if(本地存储){
    setItem(JSON.stringify(data));
    }
    window.close();
    
    反过来做。从主(打开器)窗口跟踪子弹出窗口的状态,您可以很容易地知道子窗口何时被导航回您的域,这样您就可以再次与它“交谈”。但是不要单独关闭子窗口。让打开器窗口从子窗口获取结果,然后关闭它

    例如,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>
    
    <!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>
    
    
    主要的
    window.addEventListener(“消息”,函数(ev){
    如果(ev.data.message==“deliverResult”){
    警报(“结果:+ev.data.result”);
    ev.source.close();
    }
    });
    函数Go(){
    var child=window.open(“child.html”,“_blank”,“height=200,width=200”);
    var leftDomain=false;
    var interval=setInterval(函数(){
    试一试{
    if(child.document.domain===document.domain){
    if(leftDomain&&child.document.readyState==“完成”){
    //当子窗口返回到我们的域时,我们就在这里
    间隔时间;
    警报(“返回:“+child.document.URL”);
    postMessage({message:“requestResult”},“*”);
    }
    }
    否则{
    //永远不要接触到这个代码,
    //当x站点安全检查抛出
    //但以防万一
    leftDomain=true;
    }
    }
    捕获(e){
    //当子窗口被导航离开或关闭时,我们就在这里
    如果(子项关闭){
    间隔时间;
    警报(“关闭”);
    返回;
    }
    //导航到另一个域
    leftDomain=true;
    }
    }, 500);
    }
    去
    
    child.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>
    
    <!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>
    
    
    小孩
    window.addEventListener(“消息”,函数(ev){
    if(ev.data.message==“requestResult”){
    //ev.source是开门红
    postMessage({message:“deliverResult”,result:true},“*”);
    }   
    });
    准备好后,单击浏览器后退按钮。
    

    通过IE10测试。

    在我的公司中,我们有不同的域,在这种情况下,内部网的站点必须获得我们的公共网站(以最终消除重复数据的维护)。 受Ben醋的启发,我想到了这个简单的解决方案,避免了:

    调用域网页(在我的情况下与外部网页同名)

    本地'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>"; }
      ?>
    

    使用localStorage或IndexedDB在显示来自同一域但彼此没有引用的文档的窗口之间进行通信

    只要有一个高速定时器检查数据,保存另一段数据以确认接收,另一个窗口就可以找到它并关闭


    简言之,您可以使用localStorage传递命令,甚至可以使用一个库来执行此操作,并在执行命令后删除命令,并发布返回值。

    您可以使用针对此特定场景提供的
    window.postMessage()


    说明:

    新窗口将如何与之通信