cookie常识.docx
《cookie常识.docx》由会员分享,可在线阅读,更多相关《cookie常识.docx(9页珍藏版)》请在冰豆网上搜索。
cookie常识
网络编程基础:
Cookies知识介绍与实践
一,前言
Cookies想必所有人都了解,但是未必所有人都精通。
本文讲解了Cookies的各方面知识,并且提出来了最佳实践。
这是笔者在日常工作中的积累和沉淀。
二,基础知识
1.什么是Cookies
Cookie是一小段文本信息,伴随着用户请求和页面在Web服务器和浏览器之间传递。
Cookie包含每次用户访问站点时Web应用程序都可以读取的信息。
例如,如果在用户请求站点中的页面时应用程序发送给该用户的不仅仅是一个页面,还有一个包含日期和时间的Cookie,用户的浏览器在获得页面的同时还获得了该Cookie,并将它存储在用户硬盘上的某个文件夹中。
以后,如果该用户再次请求您站点中的页面,当该用户输入URL时,浏览器便会在本地硬盘上查找与该URL关联的Cookie。
如果该Cookie存在,浏览器便将该Cookie与页请求一起发送到您的站点。
然后,应用程序便可以确定该用户上次访问站点的日期和时间。
您可以使用这些信息向用户显示一条消息,也可以检查到期日期。
Cookie与网站关联,而不是与特定的页面关联。
因此,无论用户请求站点中的哪一个页面,浏览器和服务器都将交换Cookie信息。
用户访问不同站点时,各个站点都可能会向用户的浏览器发送一个Cookie;浏览器会分别存储所有Cookie。
Cookie帮助网站存储有关访问者的信息。
一般来说,Cookie是一种保持Web应用程序连续性(即执行状态管理)的方法。
除短暂的实际交换信息的时间外,浏览器和Web服务器间都是断开连接的。
对于用户向Web服务器发出的每个请求,Web服务器都会单独处理。
但是在很多情况下,Web服务器在用户请求页时识别出用户会十分有用。
例如,购物站点上的Web服务器跟踪每位购物者,这样站点就可以管理购物车和其他的用户特定信息。
因此,Cookie可以作为一种名片,提供相关的标识信息帮助应用程序确定如何继续执行。
使用Cookie能够达到多种目的,所有这些目的都是为了帮助网站记住用户。
例如,一个实施民意测验的站点可以简单地将Cookie作为一个Boolean值,用它来指示用户的浏览器是否已参与了投票,这样用户便无法进行第二次投票。
要求用户登录的站点则可以通过Cookie来记录用户已经登录,这样用户就不必每次都输入凭据。
2.Cookies如何存储
Cookies保存在用户的本地机器上,不同的浏览器存储在不同的文件夹中,并且按照域名分别保存。
即网站之间的Cookies不会彼此覆盖。
IE浏览器的用户可以通过在本地的文档中找到Cookies的txt文件,不同操作系统的位置不同,windowsserver2003/xp都保存在:
C:
\DocumentsandSettings\Administrator\Cookies文件夹下。
其中名称txt按照域名保存,比如localhost域下的cookies为:
administrator@localhost[1].txt或者administrator@localhost[2].txt
其中后面的[1]和[2]是随着每次保存交替变化的。
3.Cookies如何传递
Cookies的信息是在Web服务器和浏览器之间传递的。
保存在Http请求中。
(1)请求页面
在请求一个页面的Http头中,会将属于此页面的本地Cookies信息加在Http头中,注意下面加粗的部分:
GET/Cookies/Test.aspxHTTP/1.1Host:
localhost:
1335User-Agent:
Mozilla/5.0(Windows;U;WindowsNT5.2;zh-CN;rv:
1.9.1.1)Gecko/20090715Firefox/3.5.1GTB5(.NETCLR3.5.30729)Accept:
text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8Accept-Language:
zh-cn,zh;q=0.5Accept-Encoding:
gzip,deflateAccept-Charset:
GB2312,utf-8;q=0.7,*;q=0.7Keep-Alive:
300Connection:
keep-aliveCookie:
My.Common.TestCookieInfo=Pkid=999&TestValue=aaabbbcccdddeee
(2)页面响应
如果页面要求写入Cookies信息,则返回的Http如下,注意加粗的部分:
HTTP/1.x200OKServer:
ASP.NETDevelopmentServer/9.0.0.0Date:
Thu,06Aug200903:
40:
59GMTX-AspNet-Version:
2.0.50727Set-Cookie:
My.Common.TestCookieInfo=Pkid=999&TestValue=aaabbbcccdddeee;expires=Fri,07-Aug-200903:
40:
59GMT;path=/Cache-Control:
privateContent-Type:
text/html;charset=utf-8Content-Length:
558Connection:
Close
4.Cookies如何查看
(1)查看Cookies的txt文件
IE用户可以直接查看Cookies的txt文件。
比如:
C:
\DocumentsandSettings\Administrator\Cookies\administrator@localhost[1].txt
(2)使用插件
FF下使用WebDeveloper插件可以很方便的查看、删除和修改Cookies:
查看页面Cookies:
点击查看大图
三.Cookies高级知识
1.Cookie的限制
大多数浏览器支持最大为4096字节的Cookie。
浏览器还限制站点可以在用户计算机上存储的Cookie的数量。
大多数浏览器只允许每个站点存储20个Cookie;注意这里的20个是指主键值,也就是20条Cookies记录,但是每个Cookies记录还可以包含若干子键,下面会详细解释。
如果试图存储更多Cookie,则最旧的Cookie便会被丢弃。
有些浏览器还会对它们将接受的来自所有站点的Cookie总数作出绝对限制,通常为300个。
2.Cookies的存储格式
Cookies可以包含一个主键,主键再包含子键。
比如中获取Cookies的格式是:
Request.Cookies[key][subkey].ToString();
其中的key就是主键,subkey就是主键关联的子键。
(1)本地磁盘存储格式:
My.Common.TestCookieInfoPkid=999&TestValue=aaabbbcccdddeeelocalhost/1536305960396830021392234896046430021191*
其中的Pkid=999&TestValue=aaabbbcccdddeee是Cookies的值,由于使用了subkey=subvalue的格式,所以此Cookies是包含子键的。
(2)Javascript中的Cookie格式
在Javascript中给的Cookie是一个字符串,通过document.cookies获取。
字符格式如下:
My.Common.SubKey=Pkid=999&TestValue=aaabbbcccdddeee;SingleKey=SingleKeyValue
上面的字符串包含了两个Cookies,一个是不包含子键的SingleKey,一个是包含pkid和TextValue两个子键的My.Common.SubKey,两个Cookie通过“;”分割。
(3)Asp.Net中的Cookies格式
和所有的服务器端语言一样,Asp.Net中使用集合类保存Cookies集合:
publicsealedclassHttpCookieCollection:
NameObjectCollectionBase{...}
通过HttpResquest和HttpResponse对象的Cookies属性,可以获取和写入当前页面的Cookies。
3.Cookies的内容编码格式
Cookies的值中可以保存除了“;”以外的标点符号。
但是不能保存汉字。
保存汉字会出现乱码。
所以对于Cookies中的内容要进行统一的编码和解码。
为了在浏览器端和服务器端都能够进行解码和编码,所以要统一使用UTF编码格式。
主要是因为javascript中只能使用UTF编码格式。
4.Cookies的Path属性
Cookies的Path属性表示当前的Cookies可以作用在网站的那个路径下。
比如下面的两个同名的Cookies:
允许存在两个同名但是Path不同的Cookies。
无论是服务器端还是客户端,在获取时优先获取本页路径下面的Cookies。
也就是说如果在、/chapter10/路径下面的页面,获取testKey这个Cookies的值,则只能获取到testValue222222这个值。
5.Cookies的过期时间
如果保存Cookies时未设置过期时间,则Cookies的过期时间为“当前浏览器进程有效”,即和Session一样关闭浏览器后则消失。
在中还可以通过设置HttpCookie对象的过期时间为DateTime.MinValue来指定此Cookies为跟随浏览器生效。
(这句话来之不易啊,在脑袋等人的帮助下才查到的。
)
如果设置了过期时间并且大于当前时间,则会保存Cookies值。
如果设置了过期时间但是小于等于当前时间,则清除Cookies值。
6.Cookies与Session
有时我们会忽略Cookies与Session的关系。
但是两者是密不可分的。
Session的唯一标示:
SessionID是通常保存在Cookies中的(也可以保存在URL中)。
对于Asp.Net而言,SessionID保存在键值为“ASP.NET_SessionId”的Cookies中,如图:
因为Cookies的存储数量是有限制的,所以我们的系统在保存Cookies的时候一定要注意防止冲掉这一个关键的Cookies。
在下文介绍的最佳实践-以强对象方式保存Cookies的代码中特意对这个Cookies做了处理。
注意,在客户端使用javascript脚本无法获取“ASP.NET_SessionId”的Cookies,因为此Cookies在服务器端设置了HttpOnly属性为true。
ASP.Net中HttpCookie对象的HttpOnly属性指定一个Cookie是否可通过客户端脚本访问。
不能通过客户端脚本访问为true;否则为false。
默认值为false。
此属性并不能完全阻止客户端在本地获取cookies,但是可以增加通过脚本直接获取的难度。
MicrosoftInternetExplorer版本6ServicePack1和更高版本支持Cookie属性HttpOnly。
7.Cookies加密
在设置Cookies的属性时,有一个选项Secure用来控制Cookie的加密特性。
如果通过SSL连接(HTTPS)传输Cookie,则为true;否则为false。
默认为false。
如果我们保存一个Cookies并设置加密,那么在非HTTPS的页面中,无论是使用javascript还是服务器端都无法获得此Cookies。
但是在本地依然可以看到此Cookies的存在。
8.Cookies与Ajax
如果Ajax请求访问一个服务器页面,此服务器页面是可以向用户浏览器写入Cookies和Session的。
四.Cookies最佳实践
在了解了Cookies的相关知识后,下面提出最佳的事件方法。
其中包括客户端和服务器端两部分。
(1)Asp.Net中保存Cookies
通常,我们使用Request和Response对象来直接操作Cookies:
写入Cookies:
Response.Cookies["k1"].Value="k1Value";Response.Cookies["k2"]["k2-1"]="k2-1Value";Response.Cookies.Add(newHttpCookie("k3","k3Value"));
读取Cookies:
Request["k1"];Request.Cookies["k1"].Value;Request.Cookies["k2"]["k2-1"];Request.Cookies.Get(0).Value;
注意Request["k1"]这个大家熟悉的获取get和post参数的方法,同时还能够获取Cookies的值!
另外上面语句中的有些是必须通过Value属性访问的,有些则不需要。
(2)以对象方式保存Cookies
下面提供一个可以以对象方式整体保存Cookies的工具类。
并且只占用一条Cookies,所有的属性都存在子键上。
源代码:
/// ///Cookies基类。
将需要保存Cookies的数据类此类派生,可以将强类型对象在Cookies中的保存和读取。
/// /// ///2009.8.6ziqiu.zhangcreated/// /// ///假设MyCookiesInfo是从从Cookies中获取对象:
/// ///CookieInfoitem=newCookieInfo();//new以后已经从Cookies中构造了对象。
/// ///将对象保存在Cookies中:
/// ///CookieInfoitem=newCookieInfo();
///item.value="testvalue";///item.SetCookies("1");//Cookies有效期为1天
/// /// [System.Serializable]publicclassCookieInfo{
#region====================ConstructedMethod====================
/// ///构造函数/// publicCookieInfo()
{}
#endregion#region====================PublicMethod====================
/// ///得到当前Cookies的过期时间
/// ///过期时间publicDateTimeGetExpiresTime()
{
stringcookieName=GetType().ToString();
if(HttpContext.Current.Request.Cookies[cookieName]!
=null)
{
returnHttpContext.Current.Request.Cookies[cookieName].Expires;
}
returnDateTime.MinValue;
}/// ///保存Cookies,过期时间为浏览器关闭则失效。
/// ///Cookies过期事件///是否保存成功publicboolSave(){returnthis.Save(DateTime.MinValue);}
/// ///保存Cookies,需要指定过期时间。
/// ///Cookies过期事件
///是否保存成功publicboolSave(DateTimeexpiresTime)
{
stringCookieName=GetType().ToString();HttpCookieSessionCookie=null;
//对SessionId进行备份.
if(HttpContext.Current.Request.Cookies["ASP.NET_SessionId"]!
=null)
{
stringSesssionId=HttpContext.Current.Request.Cookies["ASP.NET_SessionId"].Value.ToString();
SessionCookie=newHttpCookie("ASP.NET_SessionId");SessionCookie.Value=SesssionId;
}//设定cookie过期时间.DateTimedtExpiry=expiresTime;
HttpContext.Current.Response.Cookies[CookieName].Expires=dtExpiry;
//设定cookie域名.stringdomain=string.Empty;if(HttpContext.Current.Request.Params["HTTP_HOST"]!
=null)
{
//domain="";domain=HttpContext.Current.Request.Params["HTTP_HOST"].ToString();
}//如果是或多级域名,需要转化为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(PropertyInfopiinPropertys)
{
objectoj=pi.GetValue(this,null);Typetype=pi.PropertyType;
stringvalueStr=string.Empty;if(oj!
=null&&oj.ToString()!