在父窗口中访问 iFrame 的 cookie

Posted

技术标签:

【中文标题】在父窗口中访问 iFrame 的 cookie【英文标题】:Accessing cookies of an iFrame in parent window 【发布时间】:2015-07-16 01:35:45 【问题描述】:

我正在加载不同域的 iFrame。父网站和 iFrame 网站都在我的控制之下。我正在使用 iFrame.postMessage 将消息发布到 iFrame。我通过 iFrame 加载的网站有一个 cookie(不是仅 http 的 cookie)。我需要在父站点中读取这个 cookie。

   var opIFrame=document.getElementById('opIFrame').contentWindow;

    /**
 * periodically invoking the Endpoint at OP for every six seconds
 */
setInterval(function()
    console.log('Sending polling Request From RP Client ... ' + clientId);
    document.all.opIFrame.src = endPoint;
    opIFrame.postMessage(clientId,"https://localhost:9443/oauth2/loginstatus");
    var session=getCookieValue("session_state");
    console.log('**session**'+session);
,6000);


function getCookieValue(cookieName) 
var name = cookieName + "=";
var cookies =document.cookie.split(';');
if (!cookies) 
    return null;

for (var i = 0; i < cookies.length; i++) 
    var cookie = cookies[i].trim();
    if (cookie.indexOf(name) == 0) 
        return cookie.substring(name.length, cookie.length);
    

return null;

我使用上述方法读取cookie。但这并不成功。请在这方面给我建议。

更新代码:

<iframe id="opIFrame" style='visibility: hidden;' src=endpoint onload="getCookieValue('session_state')" >
</iframe> 
   <script>function getCookieValue(cookieName) 
        console.log("=====getCookieValue=======");
        var cookies = document.cookie;
        console.log("=====ALL cookies======="+cookies);
    </script>

虽然我可以在浏览器中看到 cookie,但我得到的 cookie 数组为空。

【问题讨论】:

你是如何在父窗口监听消息事件的? 是的,马尼克。我已经添加了一个 eventListner 并监听响应。但问题在于访问 cookie。我正在通过侦听器从 iFrame 获取消息事件的响应。虽然我有一个名为“session_state”的 cookie,但在执行 getCookieValue(cookieName) 时我得到了 null。 请查看我更新的答案,您能解释一下您在 clientId 中发送的内容吗?我还看到您在读取 ​​cookie 之前将消息发布到父窗口是故意的吗? 您做错了,您试图在无法访问的父窗口中读取 iframe 的 cookie,这是一种浏览器安全措施。只有创建 cookie 的域才能读取其 cookie。因此,您必须从 iframe 中读取 cookie,然后将其传递给父窗口。如果您无法访问或控制 iframe 中的页面,则无法获取 cookie 值。 对于这种情况,我只有一个解决方案 - “不可能”。 【参考方案1】:

这将为您提供 iframe 的 cookie:

var cookie = document.getElementById("iframeId").contentDocument.cookie;

要按名称获取 cookie,请使用此函数 (from ***):

function getCookie(cookie, name) 
    function escape(s)  return s.replace(/([.*+?\^$()|\[\]\/\\])/g, '\\$1'); ;
    var match = cookie.match(RegExp('(?:^|;\\s*)' + escape(name) + '=([^;]*)'));
    return match ? match[1] : null;

【讨论】:

这在不同的域中不起作用(这是问题的一部分),你会得到:SecurityError: Permission denied to access property "contentDocument" on cross-origin object 嗯有道理 在 chrome 中使用 contentWindow 而不是 cof contentDocument: document.getElementById("iframeId").contentWindow.cookie;【参考方案2】:

我不确定你是如何在父窗口上捕捉 postMessage 的,甚至不捕捉,但下面是你应该在父窗口上从子 iframe 捕捉 postMessage 的代码-

<script>
    window.addEventListener( "clientId",
      function (e) 
            if(e.origin !== 'https://localhost:9443') return;  
            alert(e.data);
      ,
      false);
</script>

更新: 我在最后复制了你的场景,发现你应该使用-

document.cookie.split(';');
parent.postMessage(clientId,"https://localhost:9443/oauth2/loginstatus");

而不是-

opIFrame.cookie.split(';');
opIFrame.postMessage(clientId,"https://localhost:9443/oauth2/loginstatus");

完整代码父窗口: - http://localhost:8541

<div>
     <h1>Parent Window</h1>
     <iframe src="http://localhost:50761/parent/test"  ></iframe>
     <script>
         window.addEventListener("message",
         function (e) 
            if (e.origin !== 'http://localhost:50761')  return; 
               alert(e.data);
            ,false);
     </script>
</div>

iFrame 页面: - http://localhost:50761

<div>
    <h1>iFrame Window</h1>
    <script type="text/javascript">
        function createCookie(name, value, days) 
            if (days) 
                var date = new Date();
                date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
                var expires = "; expires=" + date.toGMTString();
            
            else var expires = "";
            document.cookie = name + "=" + value + expires + "; path=/";
        

        function readCookie(name) 
            var nameEQ = name + "=";
            var ca = document.cookie.split(';');
            for (var i = 0; i < ca.length; i++) 
                var c = ca[i];
                while (c.charAt(0) == ' ') c = c.substring(1, c.length);
                if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
            
            return null;
        
        createCookie('testCookie', "test content", 1);
        parent.postMessage(readCookie('testCookie'), "http://localhost:8541/");
    </script>
</div>

在上面的代码中,您可以看到我在跨域环境中访问 c​​ookie 值,即父窗口在不同的域上运行,而 iframe 中的页面加载在不同的域上运行。

我创建了一个包含测试数据的测试 cookie,并使用 postMessage 传递给父窗口。

【讨论】:

我已经完成了这部分。访问cookie时出现问题。 我只需要传递一个字符串作为客户端 ID。通过代码,我提出了发布消息以将消息发布到 iframe,而不是父级。我错误地将 opIFrame.postMessage 而不是文档。我改变了它。但我仍然无法使用父级访问 iframe 中的 cookie。 您只能在同一个 iframe 中读取 iframe 的 cookie,读取后您可以使用 postMessage 将 cookie 值传递给父窗口。如果您想查看,我可以发布此代码。 我通过在 iFrame 加载时调用 getCookieValue 函数进行了尝试。但我无法访问 cookie。如果可以的话,请把代码。我已经用我的新代码更新了这个问题。 请查看更新后的答案 我现在已经添加了完整的代码。

以上是关于在父窗口中访问 iFrame 的 cookie的主要内容,如果未能解决你的问题,请参考以下文章

在iframe窗体内 获取父级的元素;;在父窗口中获取iframe中的元素

从父窗口访问 iframe 中的 DOM 附加函数

iframe 的链接在父窗口中打开

jquery,iframe,如何在父窗口监听,子窗口发生改变时,父窗口获取子窗口的值

使用 JavaScript 在父窗口中打开 iFrame 表单成功

在父窗口的上下文中运行脚本