博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
iframe 跨域访问session/cookie丢失问题解决方法
阅读量:6149 次
发布时间:2019-06-21

本文共 3152 字,大约阅读时间需要 10 分钟。

hot3.png

今天因工作需要,在一个域名A的页面中,使用iframe包含另一个域名B的页面。在chrome,firefox测试一切正常。

当测试到IE7时,发现域名B中的页面session失效,不能写入session。

网上搜索后了解, 因为IE有安全策略,限制页面不保存第三方cookie(当前访问域名A下的页面为第一方cookie,而域名B下的页面为第三方cookie)。

虽然有安全策略限制,但我们可以引入P3P声明允许第三方收集个人信息,使第三方cookie不被拒绝。

P3P:Platform for Privacy Preferences(隐私偏好平台)是W3C公布的一项隐私保护推荐标准,能够保护在线隐私权。使用Internet者可以选择在浏览网页时,是否被第三方收集并利用自己的个人信息。如果一个站点不遵守P3P标准,它的Cookies将被自动拒绝。

在iframe的页面头加入以下语句即可解决session失效问题。

[php]   

  1. header('P3P: CP="CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR"');  

a.com/index.php

[html]   

  1. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">  

  2. <html>  

  3.  <head>  

  4.   <meta http-equiv="content-type" content="text/html;charset=utf-8">  

  5.   <title> domain A page </title>  

  6.  </head>  

  7.   

  8.  <body>  

  9.   <p>A Page</p>  

  10.   <iframe src="http://b.com/index.php"></iframe>  

  11.  </body>  

  12. </html>  

b.com/index.php

[php]   

  1. <?php  

  2. header('P3P: CP="CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR"');  

  3. session_start();  

  4. $_SESSION['code'] = md5(microtime(true));  

  5. ?>  

  6. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">  

  7. <html>  

  8.  <head>  

  9.   <meta http-equiv="content-type" content="text/html;charset=utf-8">  

  10.   <title> domain B page </title>  

  11.  </head>  

  12.   

  13.  <body>  

  14.   <p>B Page</p>  

  15.   <?php  

  16.   if(isset($_SESSION['code'])){  

  17.     echo 'code:'.$_SESSION['code'];  

  18.   }  

  19.   ?>  

  20.  </body>  

  21. </html>  

IE iframe 跨域访问session问题解决了,但测试后发现,即使加入了P3P,safari浏览器依然不能保存iframe页面中的session。

原来safari的安全策略是,当cookie并未以第一方cookie保存过的(非iframe),将判断为不安全而直接拒绝。因此与IE的P3P有些不同。

解决方法如下:

首先在iframe的页面中判断某个session值是否存在。如果不存在,使用js修改window.top.location跳到一个本域的setSession.php页面。

因为是用window.top.location打开,因此并非iframe去访问,且能以第一方cookie保存.

然后在setSession.php页面执行完set session后,会跳回A域名的页面。之后就能使用session而不失效了。

代码如下:

a.com/index.php

[html]   

  1. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">  

  2. <html>  

  3.  <head>  

  4.   <meta http-equiv="content-type" content="text/html;charset=utf-8">  

  5.   <title> domain A page </title>  

  6.  </head>  

  7.   

  8.  <body>  

  9.   <p>A Page</p>  

  10.   <iframe src="http://b.com/index.php"></iframe>  

  11.  </body>  

  12. </html>  

b.com/index.php

[php]   

  1. <?php  

  2. header('P3P: CP="CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR"');  

  3. session_start();  

  4.   

  5. $ua = $_SERVER['HTTP_USER_AGENT'];  

  6. // 如果是safari  

  7. if(strstr($ua'Safari')!='' && strstr($ua'Chrome')==''){  

  8.     // 如果未设置第一方cookie  

  9.     if(!isset($_SESSION['safari'])){  

  10.         echo '<script type="text/javascript"> window.top.location="http://b.com/setSession.php"; </script>';  

  11.         exit();  

  12.     }  

  13. }  

  14.   

  15. $_SESSION['code'] = md5(microtime(true));  

  16. ?>  

  17. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">  

  18. <html>  

  19.  <head>  

  20.   <meta http-equiv="content-type" content="text/html;charset=utf-8">  

  21.   <title> domain B page </title>  

  22.  </head>  

  23.   

  24.  <body>  

  25.   <p>B Page</p>  

  26.   <?php  

  27.   if(isset($_SESSION['code'])){  

  28.     echo 'code:'.$_SESSION['code'];  

  29.   }  

  30.   ?>  

  31.  </body>  

  32. </html>  

b.com/setSession.php

[php]   

  1. <?php  

  2. header('P3P: CP="CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR"');  

  3. session_start();  

  4. $_SESSION['safari'] = 1;  

  5. header('location:http://a.com/index.php');  

  6. ?>  

源码下载地址:

转载于:https://my.oschina.net/yonghan/blog/615402

你可能感兴趣的文章
NoSQL精粹读书笔记-第1章
查看>>
ARM中断基础知识
查看>>
重载输出操作符("<<")时遇到的问题
查看>>
python中PyQwt的使用
查看>>
Linux下安装MySQL 8.0
查看>>
学习hadoop之基于protocol buffers的 RPC
查看>>
Pav OpenCart 商城自适应主题模板 ABC-0006-03
查看>>
[Android]How to use FFmpeg to decode Android f...
查看>>
memcached
查看>>
vim学习(mac下)
查看>>
Calendar获取时间的月和日
查看>>
jquery中国省市信息联动插件
查看>>
Java集合(四)LinkedList源码分析及使用示例
查看>>
logback日志交给logstash处理
查看>>
SpringCloud |第三篇: 服务消费者(Feign+REST)
查看>>
wordpress“建立数据库连接时出错”解决方案
查看>>
左手书法二十七篇
查看>>
并发中的流程控制
查看>>
用Redis存储Tomcat集群的Session
查看>>
CentOS 6.3下rsync服务器的安装与配置
查看>>