標籤:blog http java 使用 os strong io 檔案
同一網站不同子目錄的cookie要設定path,才能互相訪問。參見:
cookie path
http://www.cnblogs.com/ainiaa/archive/2011/11/18/2253841.html
以前使用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值。
看下面示範代碼:
- var cookie_name = "name";
- var cookie_value = "value";
- expires = new Date();
- expires.setTime(expires.getTime() + 86400 * 1000);
-
- // 有Bug document.cookie無法獨到cookie_name值
- document.cookie = cookie_name + "=" + encodeURIComponent(cookie_value)
- + "; expires=" + expires.toGMTString() + "; path="
- + window.location.pathname;
- // 正常
- document.cookie = cookie_name + "=" + encodeURIComponent(cookie_value)
- + "; expires=" + expires.toGMTString() + "; path=/test/";
- // 正常
- document.cookie = "cookie_name=" + encodeURIComponent(cookie_value)
- + "; 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值只對當前頁面有效,沒辦法只好用替代方案,看代碼:
- //IE Cookie Bug 替代方案
- var cookie_path = window.location.pathname;
- var cookie_name = encodeURIComponent(cookie_path.substring(cookie_path
- .lastIndexOf(‘/‘) + 1));
- cookie_path = cookie_path.substring(0, cookie_path.lastIndexOf(‘/‘) + 1);
- var cookie_value = "value";
- expires = new Date();
- expires.setTime(expires.getTime() + 86400 * 1000);
-
- document.cookie = cookie_name + "=" + encodeURIComponent(cookie_value)
- + "; 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變數。
http://blog.seateng.cn/archives/2009/03/ie-javascript-cookie-path-bug.html
這次的靜態化功能讓我學到了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;
}
這才弄明白到底是什麼原因了。
照著葫蘆畫瓢終於吧功能實現了。。。。