程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> PHP編程 >> 關於PHP編程 >> php不同子域的同名cookie問題解決方法

php不同子域的同名cookie問題解決方法

編輯:關於PHP編程

$_COOKIE是php中一個非常好用的東西,但是有時我們會碰到同域名下的不同子域名一樣,這樣就會存在只能保留一個cookie的問題,下面小編來給各位同學介紹一下。

PHP的超全局變量$_COOKIE帶來了很多便利,在某些情況下也會造成困惑。比如在根域和子域下存在同名cookie,$_COOKIE中只能保存一個,應該是哪個?

RFC建議使用長度最長的那個,這樣精度最高,但是不同浏覽器處理方式不同。我只測試了Chrome,Chrome中根域和子域的同名cookie都發送出去了,這樣PHP只接收排在前面的同名cookie,後面的被忽略,這樣很容易接收到錯誤的值。據說Safari遵循了RFC的建議,沒有親自測試,其他浏覽器也沒有測試。


首先通過SwitchHosts設定虛擬域名:www.bKjia.c0m,並且配置好Web服務器,當然,你手動設置Hosts文件也可以,我本意是為了多介紹幾個工具。

然後編寫設置Cookie的PHP腳本,先設置子域,再設置根域:

 代碼如下 復制代碼

<?php
setcookie("bar", "www", time() + 10, "/", "www.bKjia.c0m");
setcookie("bar", "foo", time() + 10, "/", ".bKjia.c0m");
?>

再編寫浏覽Cookie的腳本:

 代碼如下 復制代碼

<?php
var_dump($_COOKIE);
?>

BTW:最初寫腳本的時候我竟然在setcookie前使用了var_dump,也就是在發送請求頭之前有了輸出,犯了這樣的初學者錯誤實在是罪過,可更令人驚訝的是腳本沒有報錯,查了半天原來是因為php.ini裡缺省output_buffering = 4096。

先設置再浏覽,就能看到結果了,結果顯示有效的是子域下的Cookie。

重開一個浏覽器窗口,並使用WebDeveloper刪除Cookie,或手動刪除,避免對結果造成影響。

然後調換兩次調用setcookie的順序,也就是先設置根域,再設置子域:

 代碼如下 復制代碼

<?php
setcookie("bar", "foo", time() + 10, "/", ".bKjia.c0m");
setcookie("bar", "www", time() + 10, "/", "www.bKjia.c0m");
?>

先設置再浏覽,就能看到結果了,結果顯示有效的是根域下的Cookie。

重復兩次測試過程,並用Firebug記錄下請求頭的差異:

第一次先設置子域,再設置根域:請求頭Cookie的值是bar=www;bar=foo,結果有效的是bar=www
第二次先設置根域,再設置子域:請求頭Cookie的值是bar=foo;bar=www,結果有效的是bar=foo

也就說,同名Cookie對於服務端PHP來說,在請求頭Cookie中,哪個在前哪個生效,後面的會被忽略。

如果使用的不是Firefox,那就用不了Firebug,此時可以用PHP代碼來檢測Cookie頭:

 代碼如下 復制代碼

if (isset($_SERVER['HTTP_COOKIE'])) var_dump($_SERVER['HTTP_COOKIE']);

以上的實驗結論是基於Firefox而言的,由於不同的浏覽器發送Cookie的策略可能有差異,所以在其他浏覽器上結果可能會有所不同,比如在Safari下就始終是子域有效,其他浏覽器如Opera,Chrome等未仔細測試。鑒於這個混亂的結論,所以還是不要在子域和根域下使用同名Cookie為好!

結論:目前在根域和子域中使用同名COOKIE是非常不明智的

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved