2013-02-27 83 views
18

IE10似乎以不同于其他主流浏览器(IE8,IE9,Firefox,Chrome,Safari)的方式处理Cookie和子域名。默认情况下,IE10跨子域共享Cookie

我们使用子域名广泛的测试环境,如:

  • user1.devel.example.com
  • user2.devel.example.com
  • qa.example.com

我们的生产环境居于顶端,例如example.com(在技术上也在www.example.com上)。

我们使用php setcookie($name, $value, $expires)函数天真地(没有明确的路径或域被指定)来设置一个cookie,然后清除cookie(当用户注销时)通过给该值分配一个空字符串。这一直运行良好,每个独特的子域使用自己的cookie。

IE10现在“共享”在所有子域中设置的顶级域名(TLD)中设置的cookie。我们观察到的最初症状是没有人能够注销子域。我们观察了几件事情:

  • 尽管它共享该值,但没有子域能够清除cookie。
  • 当TLD清除cookie时,它也会立即从所有子域中删除。

有没有其他人观察到类似的行为,IE10如何存储/应用cookie相对于子域?是否有任何解决方法,除了明确发送初始Set-Cookie头时cookie应用于哪个域?

+0

我已经经历了IE10和饼干的烦恼。我不知道你的问题是否一样。看到这里我的问题的详细信息:http://stackoverflow.com/questions/15856886/ajax-on-ie10-dont-send-cookies – jmcollin92 2013-04-06 22:49:30

+0

此行为是存在于IE8和IE9了。 – 2013-09-18 14:05:32

回答

15

我刚刚遇到这个问题。

这里是某人的链接探索这个bug /问题: Cookies with and without the Domain Specified (browser inconsistency)

这也可能与: Cookie set for subdomain, but IE Developer Tools show cookie at root domain. What am I missing?

我的结论是,从非www根域名设置cookie时( http://sites.com),在IE中,这被视为所有子域的通配符cookie。 Chrome浏览器和Firefox不会显示此行为 - 它们将从非www根网域设置的Cookie设置为仅与该根网站相关联。

我使用.net webforms,IIS和我的主机文件对示例网站进行了编码。我有3个网站: a.site.com,b.site.com和site.com。他们都以完全相同的名字提供cookie。我们称之为“ShoppingCart”。

您可以在Cookie上设置多个属性,包括Cookie应关联的域。我离开这个属性被定义/左未定义.net。当Chrome收到来自每个网站的Cookie时,它会将Cookie的网域显示为显示在浏览器地址栏中列出的网域中。在IE中,情况并非如此。 IE将http://sites.com中的Cookie视为“.sites.com”,并根据RFC的cookie来表示它可以从所有子域访问。

另外,在IE浏览器,如果多个cookie设置具有相同的名称,IE他们返回到他们设定的顺序服务器。因此,如果我先访问http://sites.com,然后访问http://a.sites.com然后刷新,那么IE将http://sites.com中的cookie视为一个有效的cookie,以发送到服务器请求http://a.sites.com,该请求与http://a.sites.com的cookie一起发送,但http://sites.com的Cookie为列表中的第一个。

在.NET中,从我所看到的,饼干一般由键名,而不是访问的索引。因此,当服务器端代码尝试访问名为“ShoppingCart”的密钥的值时,它将获取设置cookie值的第一个网站的值 - 此处为http://sites.com

总之 - 当您拥有所有共享相同Cookie密钥名称的子域名时,请勿使用非www域名,因为在Chrome/Firefox处理域名关联时,正如您所期望的那样,IE会导致错误行为。

Edit--

只是为了澄清任何人读这篇文章,我使用IE10来探讨这个问题。

0

我有同样的问题在IE 11.0.9600为PHP会话cookie:Internet Explorer正在发送根域饼干及其所有子域。为了解决这个问题,我存储在会话变量域名:然后

$_SESSION['URL'] = str_replace('www.', '', $_SERVER['HTTP_HOST']); 

为每一个请求,我检查会话变量:

if (str_replace('www.', '', $_SERVER['HTTP_HOST']) != $_SESSION['URL']) { 
    session_regenerate_id(true); 
    $_SESSION = array(); 
    $_SESSION['URL'] = str_replace('www.', '', $_SERVER['HTTP_HOST']); 
} 

然后,当我们从根域移到子域名,我们不会在同一个会话中。

3

超级简单的方法,如果你有一个域的多个PHP站点解决这个问题。例如,如果您在根(example.com)上有Wordpress,并且您在子域(a.example.com)上有自定义PHP应用程序,那么无论是在您的应用程序还是Wordpress中,您都需要设置不同的SessionName 。

的会话名称()你在session_start()这应该给两个不同的名字会话,因此并不冲突之前加入。

session_name('AppSession'); 
session_start(); 

简单。

+0

是的,谢谢你,这完全为我工作。我有example.com和webapp.example.com以及来自example.com的cookie在IE中发生冲突,因此我无法登录到webapp.example.com。这对我来说是固定的,我只是将域名放入会话名称中。 '$ sesName =(isset($ _ SERVER ['HTTP_HOST'])?$ _SERVER ['HTTP_HOST']:$ _SERVER ['SERVER_NAME']); $ sesName = str_replace('。','',$ sesName); $ sesName = str_replace(' - ','',$ sesName); $ sesName = str_replace(':','',$ sesName); session_name($ sesName);' – 2016-10-26 18:31:18