简体   繁体   中英

Trying to share cookie between domains using common iframe but get two cookies instead

I have a situation where I have two different sites, siteA.com and siteB.com, which need to share a common piece of information when a visitor navigates from siteA to siteB. I don't have access to the server-side code or navigation links from siteA, only limitied customizations and javascript. In order to share the information I have built a new page that is fully under my control at siteC.com, and then added this page as an iframe to both siteA and siteB. I am using the postMessage method to get and set the cookie from within the iframe which is working fine from each site, however I actually end up with two different cookies, one for each siteA and siteB even though the cookie belongs to siteC because it was set by the page in the iframe, confirmed through F12 debugger. I would have expected to have a single cookie and both sites could share the same cookie via the iframe, am I missing something here, should this be possible or is there another way to do this?

This is the code for my page at siteC that gets loaded into the 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>

And this is code for my pages at siteA and siteB, both are using this same code, this is a sample I set up in order to test the set and get cookie functions in the iframe

<!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>

Using this setup, if I set a cookie from siteA via the iframe with a value of "keyabc=value123" for example, I can then read that same cookie back, but when I go to siteB which has the same page in the iframe there, I don't have a cookie until I set one there, for example "keyabc=value456" . Now if I look at my actual cookie files at C:\\Users\\aakoehle\\AppData\\Local\\Packages\\Microsoft.MicrosoftEdge_8wekyb3d8bbwe\\AC\\#!001\\MicrosoftEdge\\Cookies I see two files, one with each of the values I set and both have the path of siteC. I also launched the F12 tools for each browser tab, each tab shows it's own cookie belonging to siteC.

-- UPDATE --

With the current version of my code posted here I am now only seeing the cookie issue in the Edge browser. Chrome and IE are sharing a single cookie between siteA and siteB as expected.

Here's an example for sharing data between cross origin sites, using localStorage and postMessage .

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>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM