主頁(yè) > 知識(shí)庫(kù) > Cookies的各方面知識(shí)(基礎(chǔ)/高級(jí))深度了解

Cookies的各方面知識(shí)(基礎(chǔ)/高級(jí))深度了解

熱門標(biāo)簽:電子圍欄 服務(wù)器配置 Linux服務(wù)器 團(tuán)購(gòu)網(wǎng)站 Mysql連接數(shù)設(shè)置 阿里云 銀行業(yè)務(wù) 科大訊飛語(yǔ)音識(shí)別系統(tǒng)

一,前言

Cookies想必所有人都了解, 但是未必所有人都精通。本文講解了Cookies的各方面知識(shí)。

二,基礎(chǔ)知識(shí)

1.什么是Cookies

Cookie 是一小段文本信息,伴隨著用戶請(qǐng)求和頁(yè)面在 Web 服務(wù)器和瀏覽器之間傳遞。Cookie 包含每次用戶訪問(wèn)站點(diǎn)時(shí) Web 應(yīng)用程序都可以讀取的信息。

例如,如果在用戶請(qǐng)求站點(diǎn)中的頁(yè)面時(shí)應(yīng)用程序發(fā)送給該用戶的不僅僅是一個(gè)頁(yè)面,還有一個(gè)包含日期和時(shí)間的 Cookie,用戶的瀏覽器在獲得頁(yè)面的同時(shí)還獲得了該 Cookie,并將它存儲(chǔ)在用戶硬盤上的某個(gè)文件夾中。

以后,如果該用戶再次請(qǐng)求您站點(diǎn)中的頁(yè)面,當(dāng)該用戶輸入 URL 時(shí),瀏覽器便會(huì)在本地硬盤上查找與該 URL 關(guān)聯(lián)的 Cookie。如果該 Cookie 存在,瀏覽器便將該 Cookie 與頁(yè)請(qǐng)求一起發(fā)送到您的站點(diǎn)。然后,應(yīng)用程序便可以確定該用戶上次訪問(wèn)站點(diǎn)的日期和時(shí)間。您可以使用這些信息向用戶顯示一條消息,也可以檢查到期日期。

Cookie 與網(wǎng)站關(guān)聯(lián),而不是與特定的頁(yè)面關(guān)聯(lián)。因此,無(wú)論用戶請(qǐng)求站點(diǎn)中的哪一個(gè)頁(yè)面,瀏覽器和服務(wù)器都將交換 Cookie 信息。用戶訪問(wèn)不同站點(diǎn)時(shí),各個(gè)站點(diǎn)都可能會(huì)向用戶的瀏覽器發(fā)送一個(gè) Cookie;瀏覽器會(huì)分別存儲(chǔ)所有 Cookie。

Cookie 幫助網(wǎng)站存儲(chǔ)有關(guān)訪問(wèn)者的信息。一般來(lái)說(shuō),Cookie 是一種保持 Web 應(yīng)用程序連續(xù)性(即執(zhí)行狀態(tài)管理)的方法。除短暫的實(shí)際交換信息的時(shí)間外,瀏覽器和 Web 服務(wù)器間都是斷開連接的。對(duì)于用戶向 Web 服務(wù)器發(fā)出的每個(gè)請(qǐng)求,Web 服務(wù)器都會(huì)單獨(dú)處理。但是在很多情況下,Web 服務(wù)器在用戶請(qǐng)求頁(yè)時(shí)識(shí)別出用戶會(huì)十分有用。例如,購(gòu)物站點(diǎn)上的 Web 服務(wù)器跟蹤每位購(gòu)物者,這樣站點(diǎn)就可以管理購(gòu)物車和其他的用戶特定信息。因此,Cookie 可以作為一種名片,提供相關(guān)的標(biāo)識(shí)信息幫助應(yīng)用程序確定如何繼續(xù)執(zhí)行。

使用 Cookie 能夠達(dá)到多種目的,所有這些目的都是為了幫助網(wǎng)站記住用戶。例如,一個(gè)實(shí)施民意測(cè)驗(yàn)的站點(diǎn)可以簡(jiǎn)單地將 Cookie 作為一個(gè) Boolean 值,用它來(lái)指示用戶的瀏覽器是否已參與了投票,這樣用戶便無(wú)法進(jìn)行第二次投票。要求用戶登錄的站點(diǎn)則可以通過(guò) Cookie 來(lái)記錄用戶已經(jīng)登錄,這樣用戶就不必每次都輸入憑據(jù)。

2.Cookies如何存儲(chǔ)

Cookies保存在用戶的本地機(jī)器上,不同的瀏覽器存儲(chǔ)在不同的文件夾中,并且按照域名分別保存。即網(wǎng)站之間的Cookies不會(huì)彼此覆蓋。

IE瀏覽器的用戶可以通過(guò)在本地的文檔中找到Cookies的txt文件, 不同操作系統(tǒng)的位置不同,windows server 2003/xp都保存在:

C:\Documents and Settings\Administrator\Cookies 文件夾下。

其中名稱txt按照域名保存,比如localhost域下的cookies為:

administrator@localhost[1].txt 或者 administrator@localhost[2].txt

其中后面的[1]和[2]是隨著每次保存交替變化的。

3.Cookies如何傳遞

Cookies的信息是在Web服務(wù)器和瀏覽器之間傳遞的。保存在Http請(qǐng)求中。

(1)請(qǐng)求頁(yè)面

在請(qǐng)求一個(gè)頁(yè)面的Http頭中,會(huì)將屬于此頁(yè)面的本地Cookies信息加在Http頭中,注意下面加粗的部分:

復(fù)制代碼 代碼如下:

GET /Cookies/Test.aspx HTTP/1.1
Host: localhost:1335
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.2; zh-CN; rv:1.9.1.1) Gecko/20090715 Firefox/3.5.1 GTB5 (.NET CLR 3.5.30729)
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-cn,zh;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: GB2312,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Cookie: My.Common.TestCookieInfo=Pkid=999TestValue=aaabbbcccdddeee

(2)頁(yè)面響應(yīng)

如果頁(yè)面要求寫入Cookies信息,則返回的Http如下,注意加粗的部分:

復(fù)制代碼 代碼如下:

HTTP/1.x 200 OK
Server: ASP.NET Development Server/9.0.0.0
Date: Thu, 06 Aug 2009 03:40:59 GMT
X-AspNet-Version: 2.0.50727
Set-Cookie: My.Common.TestCookieInfo=Pkid=999TestValue=aaabbbcccdddeee; expires=Fri, 07-Aug-2009 03:40:59 GMT; path=/
Cache-Control: private
Content-Type: text/html; charset=utf-8
Content-Length: 558
Connection: Close

4.Cookies如何查看

(1)查看Cookies的txt文件

IE用戶可以直接查看Cookies的txt文件。
比如:C:\Documents and Settings\Administrator\Cookies\administrator@localhost[1].txt

(2)使用插件

FF下使用Web Developer插件可以很方便的查看、刪除和修改Cookies:

插件截圖:

 

查看頁(yè)面Cookies:

三. Cookies高級(jí)知識(shí)

1.Cookie 的限制

大多數(shù)瀏覽器支持最大為 4096 字節(jié)的 Cookie。

瀏覽器還限制站點(diǎn)可以在用戶計(jì)算機(jī)上存儲(chǔ)的 Cookie 的數(shù)量。大多數(shù)瀏覽器只允許每個(gè)站點(diǎn)存儲(chǔ) 20 個(gè) Cookie;注意這里的20個(gè)是指主鍵值,也就是20條Cookies記錄,但是每個(gè)Cookies記錄還可以包含若干子鍵,下面會(huì)詳細(xì)解釋。如果試圖存儲(chǔ)更多 Cookie,則最舊的 Cookie 便會(huì)被丟棄。有些瀏覽器還會(huì)對(duì)它們將接受的來(lái)自所有站點(diǎn)的 Cookie 總數(shù)作出絕對(duì)限制,通常為 300 個(gè)。

2.Cookies的存儲(chǔ)格式

Cookies可以包含一個(gè)主鍵, 主鍵再包含子鍵。比如asp.net中獲取Cookies的格式是:

復(fù)制代碼 代碼如下:

Request.Cookies[key][subkey].ToString();

其中的key就是主鍵,subkey就是主鍵關(guān)聯(lián)的子鍵。

(1)本地磁盤存儲(chǔ)格式:

復(fù)制代碼 代碼如下:

My.Common.TestCookieInfo
Pkid=999TestValue=aaabbbcccdddeee
localhost/
1536
3059603968
30021392
2348960464
30021191
*

其中的Pkid=999TestValue=aaabbbcccdddeee 是Cookies的值,由于使用了subkey=subvalue的格式, 所以此Cookies是包含子鍵的。

(2)Javascript中的Cookie格式

在Javascript中給的Cookie是一個(gè)字符串,通過(guò)document.cookies獲取。字符格式如下:

My.Common.SubKey=Pkid=999TestValue=aaabbbcccdddeee; SingleKey=SingleKeyValue

上面的字符串包含了兩個(gè)Cookies,一個(gè)是不包含子鍵的SingleKey, 一個(gè)是包含pkid和TextValue兩個(gè)子鍵的My.Common.SubKey,兩個(gè)Cookie通過(guò)“;”分割。

(3)Asp.Net中的Cookies格式

和所有的服務(wù)器端語(yǔ)言一樣,Asp.Net中使用集合類保存Cookies集合:

復(fù)制代碼 代碼如下:

public sealed class HttpCookieCollection : NameObjectCollectionBase
{...}

通過(guò)HttpResquest和HttpResponse對(duì)象的Cookies屬性,可以獲取和寫入當(dāng)前頁(yè)面的Cookies。

3.Cookies的內(nèi)容編碼格式

Cookies的值中可以保存除了“;”以外的標(biāo)點(diǎn)符號(hào)。但是不能保存漢字。保存漢字會(huì)出現(xiàn)亂碼。

所以對(duì)于Cookies中的內(nèi)容要進(jìn)行統(tǒng)一的編碼和解碼。為了在瀏覽器端和服務(wù)器端都能夠進(jìn)行解碼和編碼, 所以要統(tǒng)一使用UTF編碼格式。

主要是因?yàn)閖avascript中只能使用UTF編碼格式。

4.Cookies的Path屬性

Cookies的Path屬性表示當(dāng)前的Cookies可以作用在網(wǎng)站的那個(gè)路徑下。

比如下面的兩個(gè)同名的Cookies:

允許存在兩個(gè)同名但是Path不同的Cookies。

無(wú)論是服務(wù)器端還是客戶端,在獲取時(shí)優(yōu)先獲取本頁(yè)路徑下面的Cookies。

也就是說(shuō)如果在、/chapter10/路徑下面的頁(yè)面, 獲取testKey這個(gè)Cookies的值,則只能獲取到testValue222222這個(gè)值。

5.Cookies的過(guò)期時(shí)間

如果保存Cookies時(shí)未設(shè)置過(guò)期時(shí)間, 則Cookies的過(guò)期時(shí)間為“當(dāng)前瀏覽器進(jìn)程有效”,即和Session一樣關(guān)閉瀏覽器后則消失。在asp.net中還可以通過(guò)設(shè)置HttpCookie對(duì)象的過(guò)期時(shí)間為DateTime.MinValue來(lái)指定此Cookies為跟隨瀏覽器生效。(這句話來(lái)之不易啊,在腦袋等人的幫助下才查到的。)

如果設(shè)置了過(guò)期時(shí)間并且大于當(dāng)前時(shí)間,則會(huì)保存Cookies值。

如果設(shè)置了過(guò)期時(shí)間但是小于等于當(dāng)前時(shí)間,則清除Cookies值。

6.Cookies與Session

有時(shí)我們會(huì)忽略Cookies與Session的關(guān)系。但是兩者是密不可分的。

Session的唯一標(biāo)示:SessionID是通常保存在Cookies中的(也可以保存在URL中)。對(duì)于Asp.Net而言,SessionID保存在鍵值為“ASP.NET_SessionId”的Cookies中,如圖:

因?yàn)镃ookies的存儲(chǔ)數(shù)量是有限制的,所以我們的系統(tǒng)在保存Cookies的時(shí)候一定要注意防止沖掉這一個(gè)關(guān)鍵的Cookies。在下文介紹的最佳實(shí)踐-以強(qiáng)對(duì)象方式保存Cookies的代碼中特意對(duì)這個(gè)Cookies做了處理。

7.Cookies加密

在設(shè)置Cookies的屬性時(shí),有一個(gè)選項(xiàng)Secure用來(lái)控制Cookie的加密特性。

如果通過(guò) SSL 連接 (HTTPS) 傳輸 Cookie,則為 true;否則為 false。默認(rèn)為 false。

如果我們保存一個(gè)Cookies并設(shè)置加密,那么在非HTTPS的頁(yè)面中,無(wú)論是使用javascript還是服務(wù)器端都無(wú)法獲得此Cookies。但是在本地依然可以看到此Cookies的存在。

8.Cookies與Ajax

如果Ajax請(qǐng)求訪問(wèn)一個(gè)服務(wù)器頁(yè)面,此服務(wù)器頁(yè)面是可以向用戶瀏覽器寫入Cookies和Session的。

四. Cookies最佳實(shí)踐

在了解了Cookies的相關(guān)知識(shí)后,下面提出最佳的事件方法。其中包括客戶端和服務(wù)器端兩部分。

(1)Asp.Net 中保存Cookies

通常,我們使用Request和Response對(duì)象來(lái)直接操作Cookies:

寫入Cookies:

復(fù)制代碼 代碼如下:

Response.Cookies["k1"].Value = "k1Value";
Response.Cookies["k2"]["k2-1"] = "k2-1Value";
Response.Cookies.Add(new HttpCookie("k3", "k3Value"));

讀取Cookies:
復(fù)制代碼 代碼如下:

Request["k1"] ;
Request.Cookies["k1"].Value ;
Request.Cookies["k2"]["k2-1"];
Request.Cookies.Get(0).Value;

注意Request["k1"]這個(gè)大家熟悉的獲取get和post參數(shù)的方法,同時(shí)還能夠獲取Cookies的值!

另外上面語(yǔ)句中的有些是必須通過(guò)Value屬性訪問(wèn)的,有些則不需要。

(2)以對(duì)象方式保存Cookies

下面提供一個(gè)可以以對(duì)象方式整體保存Cookies的工具類。并且只占用一條Cookies,所有的屬性都存在子鍵上。

源代碼:

復(fù)制代碼 代碼如下:

/// summary>
/// Cookies基類。將需要保存Cookies的數(shù)據(jù)類此類派生,可以將強(qiáng)類型對(duì)象在Cookies中的保存和讀取。
/// /summary>
/// remarks>
/// 2009.8.6 ziqiu.zhang created
/// /remarks>
/// example>
/// 假設(shè)MyCookiesInfo是從 從Cookies中獲取對(duì)象:
/// code>
/// CookieInfo item = new CookieInfo(); //new以后已經(jīng)從Cookies中構(gòu)造了對(duì)象。
/// /code>
/// 將對(duì)象保存在Cookies中:
/// code>
/// CookieInfo item = new CookieInfo();
/// item.value = "test value";
/// item.SetCookies("1"); //Cookies有效期為1天
/// /code>
/// /example>
[System.Serializable]
public class CookieInfo
{
#region ==================== Constructed Method ====================
/// summary>
/// 構(gòu)造函數(shù)
/// /summary>
public CookieInfo()
{
}
#endregion
#region ==================== Public Method ====================
/// summary>
/// 得到當(dāng)前Cookies的過(guò)期時(shí)間
/// /summary>
/// returns>過(guò)期時(shí)間/returns>
public DateTime GetExpiresTime()
{
string cookieName = GetType().ToString();
if (HttpContext.Current.Request.Cookies[cookieName] != null)
{
return HttpContext.Current.Request.Cookies[cookieName].Expires;
}
return DateTime.MinValue;
}
/// summary>
/// 保存Cookies,過(guò)期時(shí)間為瀏覽器關(guān)閉則失效。
/// /summary>
/// param name="expiresTime">Cookies過(guò)期事件/param>
/// returns>是否保存成功/returns>
public bool Save()
{
return this.Save(DateTime.MinValue);
}
/// summary>
/// 保存Cookies,需要指定過(guò)期時(shí)間。
/// /summary>
/// param name="expiresTime">Cookies過(guò)期事件/param>
/// returns>是否保存成功/returns>
public bool Save(DateTime expiresTime)
{
string CookieName = GetType().ToString();
HttpCookie SessionCookie = null;
//對(duì) SessionId 進(jìn)行備份.
if (HttpContext.Current.Request.Cookies["ASP.NET_SessionId"] != null)
{
string SesssionId = HttpContext.Current.Request.Cookies["ASP.NET_SessionId"].Value.ToString();
SessionCookie = new HttpCookie("ASP.NET_SessionId");
SessionCookie.Value = SesssionId;
}
//設(shè)定cookie 過(guò)期時(shí)間.
DateTime dtExpiry = expiresTime;
HttpContext.Current.Response.Cookies[CookieName].Expires = dtExpiry;
//設(shè)定cookie 域名.
string domain = string.Empty;
if (HttpContext.Current.Request.Params["HTTP_HOST"] != null)
{
//domain = "www.elong.com";
domain = HttpContext.Current.Request.Params["HTTP_HOST"].ToString();
}
//如果是www.elong.com或多級(jí)域名,需要轉(zhuǎn)化為elong.com
if (domain.IndexOf(".") > -1)
{
string[] temp = domain.Split('.');
if (temp.Length >= 3)
{
domain = temp[temp.Length - 2].Trim() + "." + temp[temp.Length - 1].Trim();
}
HttpContext.Current.Response.Cookies[CookieName].Domain = domain;
}
//把類的屬性, 寫入Cookie.
PropertyInfo[] Propertys = GetType().GetProperties();
foreach (PropertyInfo pi in Propertys)
{
object oj = pi.GetValue(this, null);
Type type = pi.PropertyType;
string valueStr = string.Empty;
if (oj != null oj.ToString() != string.Empty)
{
if (type == Type.GetType("System.DateTime"))
{
valueStr = ((DateTime)oj).ToString("yyyy/MM/dd HH:mm:ss", System.Globalization.DateTimeFormatInfo.InvariantInfo);
}
else
{
valueStr = oj.ToString();
}
HttpContext.Current.Response.Cookies[CookieName][pi.Name] = HttpUtility.UrlEncode(valueStr);
}
}
//如果cookie總數(shù)超過(guò)20 個(gè), 重寫ASP.NET_SessionId, 以防Session 丟失.
if (HttpContext.Current.Request.Cookies.Count > 20 SessionCookie != null)
{
if (SessionCookie.Value != string.Empty)
{
HttpContext.Current.Response.Cookies.Remove("ASP.NET_SessionId");
HttpContext.Current.Response.Cookies.Add(SessionCookie);
}
}
return true;
}
/// summary>
/// 找回Cookie值
/// /summary>
public void Load()
{
string cookieValue = string.Empty;
string CookieName = GetType().ToString();
//通過(guò)遍歷屬性, 從cookie 中找回值, 回寫到屬性.
PropertyInfo[] Propertys = GetType().GetProperties();
foreach (PropertyInfo pi in Propertys)
{
try
{
cookieValue = HttpUtility.UrlDecode(HttpContext.Current.Request.Cookies[CookieName][pi.Name].ToString());
}
catch
{
cookieValue = string.Empty;
}
if (pi.CanWrite cookieValue != null cookieValue != string.Empty)
{
try
{
object obb = cookieValue;
Type type = pi.PropertyType;
obb = Convert.ChangeType(obb, type);
pi.SetValue(this, obb, null);
}
catch { }
}
}
}
#endregion
}


使用

首先說(shuō)明如何使用此類。

為想要保存在Cookies中的類建立模型,并且繼承自CookieInfo即可。比如下面建立了MyCookieInfo類,其中包含屬性pkid,TestValue和TestDateTime:

復(fù)制代碼 代碼如下:

/// summary>
/// 保存Cookies的數(shù)據(jù)對(duì)象
/// /summary>
[System.Serializable]
public class MyCookieInfo : CookieInfo
{
private int m_Pkid = 0;
public int Pkid
{
get
{
return m_Pkid ;
}
set
{
m_Pkid = value ;
}
}

private string m_TestValue = "";
public string TestValue
{
get
{
return m_TestValue;
}
set
{
m_TestValue = value;
}
}

private DateTime m_TestDateTime = DateTime.Now;
public DateTime TestDateTime
{
get
{
return m_TestDateTime;
}
set
{
m_TestDateTime = value;
}
}
}

接下來(lái)就可以使用對(duì)象的Save和Load方法保存和讀取Cookies:
復(fù)制代碼 代碼如下:

•保存
Save方法有兩個(gè)重載,不帶參數(shù)的Save方法表示Cookies的過(guò)期時(shí)間與瀏覽器相同,即瀏覽器關(guān)閉則Cookies消失。否則需要傳入Cookies過(guò)期時(shí)間。
MyCookieInfo testCookies = new MyCookieInfo();
testCookies.Pkid = 1;
testCookies.TestValue = "中文測(cè)試";
testCookies.Save(); •讀取

MyCookieInfo testCookies = new MyCookieInfo();
testCookies.Load();
this.lblMsg.Text = "Pkid:" + testCookies.Pkid.ToString();
this.lblMsg.Text += ",TestValue:" + testCookies.TestValue.ToString();
this.lblMsg.Text += ",TestDateTime:" + testCookies.TestDateTime.ToString("yyyy/MM/dd HH:mm:ss", System.Globalization.DateTimeFormatInfo.InvariantInfo);

現(xiàn)在我們已經(jīng)可以將一個(gè)強(qiáng)類型的對(duì)象讀取和保存Cookies了。
(3)使用Javascript操作Cookies

在客戶端我們同樣需要操作Cookies。

下面是封裝了的專門用于操作Cookies的jQuery工具函數(shù)。
當(dāng)然此工具函數(shù)稍加修改,就可以變成標(biāo)準(zhǔn)的Javascript函數(shù)。

下載地址

工具函數(shù)說(shuō)明:

方法簽名: jQuery.cookie(name, subName, value,  options)

方法說(shuō)明:讀取、寫入、刪除Cookies

方法參數(shù):

名稱 說(shuō)明 舉例
name cookies的主鍵值 讀取主鍵:
$.cookie("singleKey")

寫入cookies,值為字符串:
$.cookie("singleKey", "", "singleKey-value", { expires: 1, path: "/", secure: false })
subName 子鍵名稱。在寫入時(shí)請(qǐng)傳遞空或者null 讀取子鍵:
$.cookie("multiKey", "subName1")

寫入cookies,值為對(duì)象:
var subNameObj = { subName1: "aaa", subName2: "bbb", subName3: "ccc" };$.cookie("multiKey", "", subNameObj, { expires: 1, path: "/", secure: false });
value Cookies值,可以是字符串或者對(duì)象。
如果是對(duì)象,則將對(duì)象的每個(gè)屬性保存在Cookies子鍵。
參見上面實(shí)例。
options 參數(shù):
expires:可以是數(shù)字或者Data類型的對(duì)象。
如果傳入數(shù)字表示幾天后過(guò)期。
path:路徑,默認(rèn)為域名根目錄(“/”)。
secure:是否啟用加密,默認(rèn)為否。



指定過(guò)期時(shí)間:

var myDate = new Date();myDate.setFullYear(2009, 10, 10);$.cookie("singleKey", "", "singleKey-value", { expires: myDate, secure: false })  

1天后過(guò)期:

var time = Date();$.cookie("singleKey", "", "singleKey-value", { expires: 1, path: "/", secure: false })

標(biāo)簽:衢州 萍鄉(xiāng) 蚌埠 衡水 江蘇 棗莊 廣元 大理

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《Cookies的各方面知識(shí)(基礎(chǔ)/高級(jí))深度了解》,本文關(guān)鍵詞  ;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問(wèn)題,煩請(qǐng)?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無(wú)關(guān)。
  • 相關(guān)文章
  • 收縮
    • 微信客服
    • 微信二維碼
    • 電話咨詢

    • 400-1100-266