2013-02-27 57 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