尝试使用常见的iframe在域之间共享Cookie但是获取两个Cookie

时间:2017-10-06 19:57:51

标签: javascript iframe cookies cross-domain microsoft-edge

我的情况是,我有两个不同的站点,siteA.com和siteB.com,当访问者从siteA导航到siteB时,需要共享一条公共信息。我无法访问siteA的服务器端代码或导航链接,只能限制自定义和javascript。为了共享信息,我在siteC.com上构建了一个完全由我控制的新页面,然后将此页面作为iframe添加到siteA和siteB。我使用postMessage方法从iframe中获取和设置cookie,每个网站都运行正常,但实际上我最终得到了两个不同的cookie,每个siteA和siteB一个,即使cookie属于siteC因为它是由iframe中的页面设置的,通过F12调试器确认。我本来希望有一个cookie,两个网站都可以通过iframe共享相同的cookie,我在这里遗漏了一些东西,这是否可行,还是有另外一种方法可以做到这一点?

这是我在siteC的页面加载到iframe

的代码
<!DOCTYPE html>
<html>
<head>
   <title>iframe source</title>
   <script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
   <script type="text/javascript">
      $(function () {
         var ck = document.cookie;
         var expDate = new Date();
         expDate.setFullYear(expDate.getFullYear() + 20)
         $("#auditlog").append("iframe loaded<br/>");
         if (ck) {
            $("#auditlog").append("cookie exists<br/>");
         } else {
            $("#auditlog").append("cookie not set<br/>");
         }

         // Assign handler to message event
         if (window.addEventListener) {
            window.addEventListener('message', messageHandler, false);
         } else if (window.attachEvent) { // ie8
            window.attachEvent('onmessage', messageHandler);
         }
      })

      function messageHandler(e) {
         var msg = {};
         var response;
         // Check origin
         if (e.origin === 'http://siteA' || e.origin === 'http://siteB') {
            // Retrieve data sent in postMessage
            msg = JSON.parse(e.data);
            if (msg.action == "getCookie") {
               response = getCookie();
            } else if (msg.action == "setCookie") {
               setCookie(msg.payload);
               response = "cookie set";
            } else {
               response = "action not supported";
            }
            // Send reply to source of message
            e.source.postMessage(response, e.origin);
         }
      }

      function setCookie(cookieVal) {
         var expDate = new Date();
         expDate.setFullYear(expDate.getFullYear() + 20)
         document.cookie = cookieVal + "; expires=" + expDate.toUTCString();
      }

      function getCookie() {
         return document.cookie;
      }
   </script>
</head>
<body>
   <div id="auditlog"></div>
   <div id="cookieinfo"></div>
</body>
</html>

这是我在siteA和siteB的页面的代码,两者都使用相同的代码,这是我为了测试集合并在iframe中获取cookie函数而设置的示例

<!DOCTYPE html>
<html>
<head>
   <title>Main content page</title>
   <script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
   <script type="text/javascript">
      $(function () {
         // Assign handler to message event
         if (window.addEventListener) {
            window.addEventListener('message', messageHandler, false);
         } else if (window.attachEvent) { // ie8
            window.attachEvent('onmessage', messageHandler);
         }

         $("#btnGetIframeCookie").click(function () {
            var postMsg = {
               action:"getCookie"
            }
            // get reference to window inside the iframe
            var wn = document.getElementById('cookieiframe').contentWindow;
            // postMessage arguments: data to send, target origin
            wn.postMessage(JSON.stringify(postMsg), 'http://siteC');
         })
         $("#btnSetIframeCookie").click(function () {
            var cookieVal = $("#txtCookieValue").val();
            var postMsg = {
               action: "setCookie",
               payload: cookieVal
            }
            var wn = document.getElementById('cookieiframe').contentWindow;
            // postMessage arguments: data to send, target origin
            wn.postMessage(JSON.stringify(postMsg), 'http://siteC');
         })
      })

      function messageHandler(e) {
         if (e.origin === 'http://siteC') {
            $("#divMessages").append("response from iframe: <br/>" + e.data + "<br/>");
         }
      }
   </script>
</head>
<body>
   <div>
      This is the iframe container
   </div>
   <div>
      <input type="button" id="btnGetIframeCookie" value="Get iframe cookie" />
   </div>
   <div>
      <input type="text" size="60" id="txtCookieValue" />
      <input type="button" id="btnSetIframeCookie" value="Set iframe cookie" />
   </div>
   <iframe id="cookieiframe" src="http://siteC/iframe/index.html" style="width: 300px; height: 300px; border:1px solid black;"></iframe>
   <div id="divMessages"></div>
</body>
</html>

使用此设置,如果我通过iframe通过值"keyabc=value123"设置来自siteA的cookie,我可以读回相同的cookie,但是当我转到具有相同页面的siteB时那里的iframe,我没有cookie,直到我在那里设置一个cookie,例如"keyabc=value456"。现在,如果我在C:\Users\aakoehle\AppData\Local\Packages\Microsoft.MicrosoftEdge_8wekyb3d8bbwe\AC\#!001\MicrosoftEdge\Cookies查看我的实际cookie文件,我会看到两个文件,一个是我设置的每个值,都有siteC的路径。我还为每个浏览器选项卡启动了F12工具,每个选项卡都显示了它自己的属于siteC的cookie。

- 更新 -

在我这里发布的代码的当前版本中,我现在只在Edge浏览器中看到cookie问题。 Chrome和IE正在按预期在siteA和siteB之间共享一个cookie。

1 个答案:

答案 0 :(得分:1)

以下是使用localStoragepostMessage在跨源网站之间共享数据的示例。

site1:localhost:9091

<html>
<body>
    <h1>site 1</h1>
    <button id='postBtn'>Post message</button>
    <br/>
    <iframe id='commonSite' src='http://localhost:9093/commonSite.html' style='height:150px'></iframe>

    <script>
        (function () {
            var commonSite = document.querySelector('#commonSite').contentWindow;
            var postCounter = localStorage.getItem('postCounter');
            postCounter = postCounter != null ? +postCounter : 1;

            var commonOrigin = 'http://localhost:9093';

            document.querySelector('#postBtn').onclick = function () {
                commonSite.postMessage(postCounter++, commonOrigin);
                localStorage.setItem('postCounter', postCounter);

                console.log('site 1 posted');
            }
        })();
    </script>
</body>
</html>

site2:localhost:9092

<html>
<body>
    <h1>site 2</h1>
    <button id='postBtn'>Post message</button>
    <br/>
    <iframe id='commonSite' src='http://localhost:9093/commonSite.html' style='height:150px'></iframe>

    <script>
        (function () {
            var commonSite = document.querySelector('#commonSite').contentWindow;
            var postCounter = localStorage.getItem('postCounter');
            postCounter = postCounter != null ? +postCounter : 1;

            var commonOrigin = 'http://localhost:9093';

            document.querySelector('#postBtn').onclick = function () {
                commonSite.postMessage(postCounter++, commonOrigin);
                localStorage.setItem('postCounter', postCounter);

                console.log('site 2 posted');
            }
        })();
    </script>
</body>
</html>

commonSite:localhost:9093

<html>
<body>
    <h3>Common site</h1>
    <h4> Site 1 count: <span id='count1'></span></h3>
    <h4> Site 2 count: <span id='count2'></span></h3>

    <script>
        (function () {
            console.log('Adding message listener');
            var origin1 = 'http://localhost:9091';
            var origin2 = 'http://localhost:9092';

            var count1 = document.querySelector('#count1');
            var count2 = document.querySelector('#count2');

            if(localStorage.getItem('count1')) {
                count1.textContent = localStorage.getItem('count1');
            }

            if(localStorage.getItem('count2')) {
                count2.textContent = localStorage.getItem('count2');
            }

            window.addEventListener('message', function (event) {
                var origin = event.origin;
                var data = event.data;

                if(origin === origin1) {
                    localStorage.setItem('count1', data);
                    count1.textContent = localStorage.getItem('count1');
                } else if(origin === origin2) {
                    localStorage.setItem('count2', data);
                    count2.textContent = localStorage.getItem('count2');
                }

                console.log('received (' + data + ') from ' + origin);
            }, false);
        })();
    </script>
</body>
</html>