对于IE来说(默认安全级别下),iframe、img、link等标签都是发送session cookie(又叫 第一方cookie),拦截本地cookie发送(又叫第三方cookie)。当这些标签跨域引用一个页面,实际上是发起了一次GET请求。
如果这个跨域的请求,HTTP返回头中带有Set-Cookie , 那么这个cookie对浏览器来说,实际上是无效的。
看如下测试
在 www.b.com 上有一个页面,其中包含一个指向 www.a.com 的iframe
http://www.b.com/test.html
的内容为:
<iframe width=300 height=300 src="http://www.a.com/test.php" ></iframe>
http://www.a.com/test.php
是一个对 a.com 域设置 cookie的页面,其内容为:
<?php
header("Set-Cookie: test=axis; domain=.a.com; path=/");
?>
<script>
alert(document.cookie);
</script>
此时我们请求 http://www.b.com/test.html
, 他包含一个iframe,会去跨域请求 www.a.com/test.php
,该php页面会尝试 set-cookie
第一次请求, test.php 会 set-cookie,所以浏览器会收到一个cookie。
如果 set-cookie 成功,再次请求该页面,浏览器应该会 sent 刚才 recieve 到的cookie。可是由于前面说的跨域限制,在IE里的iframe标签是 set-cookie不成功的,所以无法sent刚才收到的cookie。 这里无论是 session cookie 还是本地cookie都是一样。特别说明一点的是,这里说的只是针对IE,对于Chrome等浏览器不存在这个问题。
但是这种情况在加入了P3P header 后会改变。
P3P header允许跨域访问隐私数据,从而可以跨域set-cookie成功
我们修改 www.a.com/test.php
为
<?php
header("P3P: CP=CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR");
header("Set-Cookie: test=axis; expires=Sun, 23-Dec-2018 08:13:02 GMT; domain=.a.com; path=/");
?>
<script>
alert(document.cookie);
</script>
值得注意的是,P3P header只需要设置一次,这样跟在这个P3P header后面的所有 set-cookie,都可以跨域访问了。也就是说: 被P3P header设置过一次后,之后的请求不再需要P3P header,也能够在iframe里跨域发送这些cookie。
但是如果用 set-cookie 去改变设置好的cookie,则不再具有这种跨域访问特性。
P3P header 还有一个特点就是同一个包里只能设置一次,后面的P3P Header不会覆盖前面的P3P header,浏览器只认第一个。
页面里的COOKIE不能是浏览器进程的COOKIE(包括验证票和不设置超时时间的COOKIE),否则跨域会取不到。
参考网址: