程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> 深入了解Cookie

深入了解Cookie

編輯:關於JAVA

Cookie這個東東,第一次接觸WEB的時候,就了解它了,用起來嘛也很簡單.但是對這個東西一直缺少完整的認識,最近正好有時間,看了些資料,結合自己以前寫的代碼,在這裡做個簡單的完整介紹吧.

基本概念

Cookie是Web服務器向用戶浏覽器發送的一段Ascii文本.一旦接受到cookie,浏覽器會把cookie的信息片段以"鍵/值"對的形式保存在本地.這以後,每次想同一服務器發送請求的時候,Web浏覽器都會發送站點以前存儲在本地的cookie.浏覽器和Web服務器的通訊是通過Http協議進行通訊的,而cookie就保存在Http協議的請求部分(Set-Cookie).

具體形式如下:

Set-Cookie:customer=huangxp; path=/foo; domain=ibm.com; expires= Wednesday, 19-OCT-05 23:12:40 GMT; [secure];HttpOnly

其中每個屬性的解釋:

domain: 關聯的域名,例如http://ibm.com/foo/index.aspx, 它的domain = ibm.com,該domain默認為當前請求的域,但是如果cookie中domain的值和請求的域不相符的話,這個cookie就會被忽略.

path: 控制哪些訪問能觸發發送.例如請求的地址是上面的URL,如果path=/foo,這個cookie就會被發送,但是path為其他的話,該cookie會被忽略.

expires: cookie的過期時間

secure: 如果secure 這個詞被作為Set-Cookie 頭的一部分,那麼cookie 只能通過安全通道傳輸(目前即SSL通道)。否則,浏覽器將忽略此Cookie

HttpOnly:只是該cookie是否能被客戶端訪問,不過該數據要依賴與浏覽器是否支持,一般IE6以上的版本都支持該屬性.

"鍵/值"對: customer=huangxp或customer=a1=huangxp&a2=huangxp

介紹完Cookie的基本原理後,下面簡單描述下一次典型的網絡浏覽過程

浏覽器對於Web服務器應答包頭中Cookie的操作步驟:

1.從Web服務器的應答包頭中提取所有的cookie。

2.解析這些cookie的組成部分(名稱,值,路徑等等)。

3.判定主機是否允許設置這些cookie。允許的話,則把這些Cookie存儲在本地。

浏覽器對Web服務器請求包頭中所有的Cookie進行篩選的步驟:

1.根據請求的URL和本地存儲cookie的屬性,判斷那些Cookie能被發送給Web服務器。

2.對於多個cookie,判定發送的順序。

3.把需要發送的Cookie加入到請求HTTP包頭中一起發送。

客戶端和服務器端對Cookie的操作

它們之間的交互我想通過下面的DEMO可以更好的讓大家了解

a, 服務器端輸出Cookie,客戶端獲取Cookie

Code
protected void Page_Load(object sender, EventArgs e)
{
   HttpCookie ck = new HttpCookie("TestCK");
   ck.Values.Add("Name1", "1");
   ck.Values.Add("Name2", "2");
   HttpCookie ck1 = new HttpCookie("TestCK_2");
   ck1.Value = "1";
   this.Response.Cookies.Add(ck);
   this.Response.Cookies.Add(ck1);
}
Code
function GetCookie(){
  document.write(document.cookie);
}

服務器端輸出TestCk,TestCK_2這兩個Cookie,那麼客戶段獲取的Cookie是"TestCK=Name1=1&Name2=2; TestCK_2=1"

有些需要注意的地方:

1,客戶端的document.cookie只能獲取獲取HttpCookie的Name,Value和Values屬性.

2,如果HttpCookie中的Values有值的話,那麼在客戶端輸出的是name1=1&name2=2&......這種形式,如果Value有值,輸出的為1,如果Value和Values都有值,輸出的是1&name1=1&name2=2&...這種形式

3,多個Cookie在客戶端document.cookie中是通過";"來隔離的

b, 客戶端輸出Cookie,服務器端獲取

Code
function SetCookie(){
   document.cookie = "TestCK=Name1=1&Name2=2";
   var d1 = new Date(2008, 9, 17);
   document.cookie = "TestCK_2=1;expires=" + d1;
}

執行完上面方法後,在客戶端獲取的Cookie如下圖

服務器端獲取的Cookie:

需要注意的地方:

1, 設置多個Cookie的時候必須按照上面的設置,不能"TestCK=Name1=1&Name2=2; TestCK_2=1"這樣賦值

2, 如果要刪除Cookie,可以設置expires屬性為過期的時間,例如"document.cookie = TestCK_2=1;expires = 過期時間"

3, 對於在客戶端設置的expires..這些屬性,在服務器端獲取不到,只能獲取Value和Values屬性(至於為什麼會這樣我也沒有弄明白?)

不管在服務器端和客戶端都要注意對domain,path,httponly....這些的設置,在沒有特殊需求的時候,別去設置他們,否則可能會造成Cookie遺失.

自定義Cookie類(客戶端操作Cookie)

根據document.cookie對Cookie的支持,在賦值和獲取值的操作上還是有點麻煩,不像服務器端的HttpCookie那樣方便,則下面提供了個自己寫的在客戶端操作Cookie的對象.基本和HttpCookie相對應,目的是為了操作起來更加方便一些.

CookieObj類: 對應與HttpCookie的Name和Values, __CookieValue為私有屬性,一般不要使用,它的值為當前Name對應的document.cookie.

Set方法: 為當前Cookie賦值,設置Values屬性.

Remove方法: 根據Key刪除Values中的元素.

Get方法: 獲取默認的值,因為document.cookie的值可能為"1&name1=1&name2=2"這種形式,所以它獲取的是1的元素

GetItemByKey方法: 根據Key獲取元素

KeyValuePair類: 這個只是一個鍵/值對的類.

CookieAdapter類: 提供一種document.cookie和CookieObj之間的轉換

CookieAdapter.GetCookies方法 : 獲取所有的Cookie,並且轉換為CookieObj的數組集合.

CookieAdapter.GetCookieByName方法: 根據Cookie的名稱,來獲取對應的Cookie.

CookieAdapter.SetCookies方法: 設置document.cookie,接受的參數是由CookieObj對象組成的數組集合.

Code

/**//* Cookie類 */
function CookieObj(name){
   /**//* (Public)名稱 */
   this.Name = name;
   /**//* (Public)Cookie的鍵/值對 */
   this.KeyValues = new Array();
   /**//* (Private)document.cookie的字符串 */
   this.__CookieValue;
}
CookieObj.prototype = {
   /**//* (Public)設置鍵/值對 */
   Set : function(key, value){
     switch(arguments.length){
       case 0:
         return;
         break;
       case 1:
         if(!key){
           return;
         }
         var item = this.GetItemByKey("__Default");
         if(!item){
           item = new KeyValuePair("__Default", key);
           this.KeyValues.push(item);
         }
         else{
           item.Value = key;
         }
         break;
       case 2:
         // key或value為空
         if(!key || !value){
           return;
         }
         var item = this.GetItemByKey(key);
         //item為空的時候
         if(!item){
           item = new KeyValuePair(key, value);
           this.KeyValues.push(item);
         }
         else{
           item.Value = value;
         }
         break;
     }
   },
   /**//* (Public)刪除鍵 */
   Remove : function(key){
     //key為空
     if(!key){
       return;
     }
     var index = this._GetIndexByKey(key);
     //存在數據
     if(index > -1){
      this.KeyValues.splice(index, 1);
     }
   },
   /**//* (Public)獲取值 */
   Get : function(){
     return this.GetItemByKey("__Default");
   },
   /**//* (Public)鍵/值對的索引 */
   GetItemByKey : function(key){
     //key為空
     if(!key){
       return;
     }
     //存在數據
     if(this.KeyValues && this.KeyValues.length >0){
       for(var i=0; i< this.KeyValues.length; i++){
         var obj = this.KeyValues[i];
         //關鍵字存在
         if(obj.Key == key){
           return obj;
           break;
         }
       }
     }
     return null;
   },

/**//* (Private)獲取鍵/值對的Index */

_GetIndexByKey : function(key){

//存在數據
     if(this.KeyValues && this.KeyValues.length >0){
       for(var i=0; i< this.KeyValues.length; i++){
         var obj = this.KeyValues[i];
         //關鍵字存在
         if(obj.Key == key){
           return i;
           break;
         }
       }
     }
     return -1;
   }
}

/**//* 鍵/值對的類 */

function KeyValuePair(key, value){
   this.Key = key;
   this.Value = value;
}

/**//* Cookie和document.cookie之間的轉換,獲取,設置Cookie */

var CookieAdapter = {};

/**//* (Public)獲取所有的Cookie對象 */

CookieAdapter.GetCookies = function(){
   //Cookie對象的集合
   var arrCookieObjs = new Array();
   //Cookie存在
   if(document.cookie){
     var arrCookie = document.cookie.split(";");
     for(var i=0;i < arrCookie.length; i++){
       var mCookieObj = CookieAdapter._ConvertToCookieObj(arrCookie[i]);
       arrCookieObjs.push(mCookieObj);
     }
   }
   return arrCookieObjs;
}

/**//* (Public)獲取指定名稱的Cookie對象 */

CookieAdapter.GetCookieByName = function(name){
   //Cookie存在
   if(document.cookie){
     var arrCookie = document.cookie.split(";");
     for(var i=0;i < arrCookie.length; i++){
       var arr = arrCookie[i].split("=");
       if(arr[0] == name){
         var mCookieObj = CookieAdapter._ConvertToCookieObj(arrCookie[i]);
         return mCookieObj;
         break;
       }
     }
   }
   return null;
}

/**//* (Public)設置document.cookie */

CookieAdapter.SetCookies = function(arrCookie, expires, domain, path, secure, httponly){
   //Cookie對象不為空
   if(arrCookie){
     for(var i = 0; i< arrCookie.length; i++){
       var obj = arrCookie[i];
       var str = "";
       //存在鍵/值集合
       if(obj.KeyValues){
         for(var j =0; j< obj.KeyValues.length; j++){
           var objKey = obj.KeyValues[j];
           if(objKey.Key == "__Default"){
             str += objKey.Value;
           }
           else{
             str += objKey.Key + "=" + objKey.Value;
           }
           if(j != obj.KeyValues.length -1){
             str += "&";
           }
         }
         obj.__CookieValue = str;
       }
       if(str){
         document.cookie = obj.Name + "=" + str;
       }
       else{
         document.cookie = obj.Name;
       }
       if(expires){
         document.cookie += ";expires=" + expires;
       }
       if(domain){
         document.cookie += ";domain=" + domain;
       }
       if(path){
         document.cookie += ";path=" + path;
       }
       if(secure){
         document.cookie += ";" + secure;
       }
       if(httponly){
         document.cookie += ";" + httponly;
       }
     }
   }
}

/**//* (Private)document.cookie的轉換為Cookie對象 */

CookieAdapter._ConvertToCookieObj = function(cookieStr){
   var arr = cookieStr.split("=");
   //設置Cookie對象
   var mCookieObj = new CookieObj(arr[0]);
   if(arr.length > 1){
     var strValue = cookieStr.substring(arr[0].length + 1, cookieStr.length);
     mCookieObj.__CookieValue = strValue;
     //存在鍵/值集合
     var arrValues = strValue.split("&");
     for(var j=0 ;j < arrValues.length; j++){
       var arrKeyValue = arrValues[j].split("=");
       if(arrKeyValue.length == 1){
         mCookieObj.Set(arrKeyValue[0]);
       }
       else{
         mCookieObj.Set(arrKeyValue[0], arrKeyValue[1]);
       }
     }
   }
   return mCookieObj;
}

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