1. 程式人生 > >同一網站不同和二級域名和不同子目錄的cookie

同一網站不同和二級域名和不同子目錄的cookie

1、cookie二級域名的實現:

使用者其中一個站點登入,而且可以各個子頻道間切換,保持登入狀態設定Cookie時,使用如下程式碼即可:
setcookie(name,value,expire,path,"domain.com");
這樣,在每個二級域名都能讀取這個Cookie的值。 參見:

cookie共享於二級域名

一個cookie如上4個重要的屬性:

1)maxAge:cookie被客戶端保持的時間,單位為(秒),正數表示在指定的秒數後過期被客戶端刪除,0表示刪除此cookie(置空),負數則表示此cookie不會被客戶端儲存,將在瀏覽器關閉後清除.

2)domain:cookie可被有效操作的域,可以為ip/hostname等,不過需要宣告:*.abc.com,.abc.com,abc.com這三種方式會有區別,客戶端會做簡單的匹配.多數情況下直接使用abc.com可以接受多級子域名.只有正確匹配domain的cookie才會被髮送給server.

3)secure:是否只允許安全加密url訪問,預設為false,如果為true,那麼cookie只對https/SSL等加密連線才會傳送給server.

4)path:cookie對domain何路徑下訪問有效,"/"表示domain下根目錄中所有請求有效,"/open"表示只對domain/open目錄下請求有效,如果此path忘記設定,你將遇到一個很尷尬的問題:明明在其他頁面設定了cookie輸出,但是換個頁面卻死活不行..

domain和path是決定可跨域的2個引數.

對於domain,"abc.com"則可以在abc.com主域名之下的多級子域名有效,".abc.com"只能在二級域名以及"www.abc.com"下有效,其實客戶端只是做了簡單的匹配..你可以在此基礎上做更多的分級控制..

path是個有參考意義的屬性,對於部分路徑下開放訪問的系統有意義,比如:abc.com/open下的程式和登入是開放給特殊開發者接入的,這裡的資料活著cookie需要做一些另類的處理..

2、同一網站不同子目錄的cookie要設定path,才能互相訪問。參見: 

cookie path

以前使用cookie的時候 沒有在意path的問題。這次公司商城實現了靜態化的功能,多了2級目錄。導致了我在商品詳情頁面設定好的cookie(path為/good/商品ID/)在店鋪首頁竟然訪問不到(店鋪首頁的path為'/store/')。cookie的名稱都是一致的。唯一不同的只有path。在商品詳情頁設定cookie的時候吧path設定成‘/’,這樣修改之後就可以正常的在店鋪首頁取到設定好的cookie了。

使用關鍵字 javascript cookie  path 還搜尋到了,原來10年來IE一直存在一個cookie path的一個bug(原文地址:http://conkeyn.iteye.com/blog/423549)。

手上一個廣告專案,在Firefox下順利測試通過。自信JS程式碼能相容IE,FF測試過後隨手就仍給CS測試,結果CS反饋說有問題。排查一番, 發現居然和Javascript 設定 Cookie 時的 path 有關。IE下Cookie種在 /或者URL所在路徑時正常,如果Cookie值作用域在當前URL下則IE下javascript 無法獲取到設定的Cookie值。

看下面演示程式碼:

  1. var cookie_name = "name";  
  2. var cookie_value = "value";  
  3. expires = new Date();  
  4. expires.setTime(expires.getTime() + 86400 * 1000);  
  5. // 有Bug document.cookie無法獨到cookie_name值  
  6. document.cookie = cookie_name + "=" + encodeURIComponent(cookie_value)  
  7.         + "; expires=" + expires.toGMTString() + "; path="  
  8.         + window.location.pathname;  
  9. // 正常  
  10. document.cookie = cookie_name + "=" + encodeURIComponent(cookie_value)  
  11.         + "; expires=" + expires.toGMTString() + "; path=/test/";  
  12. // 正常  
  13. document.cookie = "cookie_name=" + encodeURIComponent(cookie_value)  
  14.         + "; expires=" + expires.toGMTString() + "; path=/";  

懷疑是IE的Bug、
在google上 搜了下關鍵詞: ie javascript cookie path bug 
同樣的問題在罪與罰 的部落格上也有描述,而且博主聯絡過微軟IEBLOG 的Eric。得到的回覆是:

You have uncovered an IE bug where cookies that are set with a path that contains a filename (e.g. /page.htm) are not accessible to the document.cookie function, although they are correctly sent to the server in the HTTP header. This has been broken for at least 10 years and unfortunately probably will not be fixed in IE8.

Thanks,

-Eric

一個存在10年的Bug。。。而且IE8也不會修復,實在是無語。

需求是cookie值只對當前頁面有效,沒辦法只好用替代方案,看程式碼:

  1. //IE Cookie Bug 替代方案  
  2. var cookie_path = window.location.pathname;  
  3. var cookie_name = encodeURIComponent(cookie_path.substring(cookie_path  
  4.         .lastIndexOf('/') + 1));  
  5. cookie_path = cookie_path.substring(0, cookie_path.lastIndexOf('/') + 1);  
  6. var cookie_value = "value";  
  7. expires = new Date();  
  8. expires.setTime(expires.getTime() + 86400 * 1000);  
  9. document.cookie = cookie_name + "=" + encodeURIComponent(cookie_value)  
  10.         + "; expires=" + expires.toGMTString() + "; path=" + cookie_path;  

 替代方案根據每個頁面的URL檔名來做Cookie名,有效範圍在當前頁路經下。
如:url 等於 /test/test.html
則cookie名為test.html,有效路徑為/test/
這樣也可以做到同一個js部署在每個頁面上能讀到只對當前URL有效的cookie值。代價是當用戶在同一級目錄下訪問很多頁面時會導致cookie值不 斷增大。結果是當前路徑下的每個http請求都帶很長一段的cookie,直接導致伺服器接收客戶端request的header長度增長,流量增長的同 時伺服器負擔也變重。而且根據 RFC 2109 的定義Cookie也有長度和個數限制,IE允許的最大 Cookie 長度是 4096 位元組,允許50個 Cookie 名-值對。如果要突破50個名-值對的限制,可以在一個名-值使用Cookie字典的方式儲存更多的Cookie變數。

這次的靜態化功能讓我學到了cookie的這個問題。很是高興啊。

這次靜態化功能還涉及到了一個跨域請求的問題。事情是這樣的:

我在搜尋模組(域名search.emall.xxx.xxx)需要顯示當前使用者的商品瀏覽歷史。二者個商品瀏覽歷史是在主站的cookie裡面儲存的。為了方便我們把COOKIE_DOMAIN都設定成了一樣的一級域名,使用js的cookie卻不能獲得設定好的cookie。但是,使用firebug + firecookie卻可以清楚的看到cookie是存在的且沒有過期。唯一不同的就好似cookie的domain和當前模組的domain一致(cookie是在主站設定好的emall.xxx.xxx,當前search的域名為search.emall.xxx.xxx)。 這很容易就讓人想到是cookie domain的問題導致的。問題原因找到了,解決它。使用js不行我就我就使用ajax的方式請求主站,在主站吧cookie取出來,然後再原樣的返回。編碼,執行,反先,ajax請求還是不能獲得(使用get的方式傳送請求)。把ajax請求的地址放在位址列裡面,確實有內容返回,但是使用ajax請求的話,還是不能獲得cookie的值。很顯然,這種情況就是傳說中的跨域請求的問題。這問題咱沒有解決過,怎麼辦那?突然想起來了,該模組下使用者登入資訊就是通過ajax非同步取出來的。同時ajax請求為什麼使用者的登入資訊可以拿到我的為什麼就拿不到???

找原因。找到請求使用者資訊的程式碼,才發現,原來請求的時候和我的ajax還有一點不一樣。請求使用者資訊的方式為:

JS程式碼如下:

複製程式碼 複製程式碼
    //跨域獲取資料
jQuery.ajax({
type : "GET",
url : temp_domain_url+"/index.php?",
data : "act=get_user_info&php_session_id="+jQuery.cookie('COOKIE_ID')+"&jsoncallback=?",
dataType : "jsonp",
jsonnp : 'callback',
success:function(data){
      ...
      ...
      ...
    }
  });
複製程式碼 複製程式碼

php程式碼如下:

複製程式碼 複製程式碼
function get_user_info()
{
$gbh_goods_info = $_COOKIE['gbh_goods_info'] ? $_COOKIE['gbh_goods_info'] : json_encode(false);
if ($gbh_goods_info && get_magic_quotes_gpc())
{//沒有這個的話會出現錯誤
$gbh_goods_info = stripslashes($gbh_goods_info);
}
$gbh_goods_info = json_decode($gbh_goods_info);
echo $_GET['callback']."({msg: ".json_encode($gbh_goods_info)."});";
exit;
}
複製程式碼 複製程式碼

這才弄明白到底是什麼原因了。

照著葫蘆畫瓢終於吧功能實現了。。。。

轉自:http://www.cnblogs.com/mitang/p/3884774.html