Cookies 揭秘
Cookies 揭秘 [Asp.Net, Javascript]
一、前言
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文件, 不同操作系统的位置不同,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服务器和浏览器之间传递的。保存在Http请求中。
(1)请求页面
在请求一个页面的Http头中, 会将属于此页面的本地Cookies信息加在Http头中,注意下面加粗的部分:
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=999&TestValue=aaabbbcccdddeee
(2)页面响应
如果页面要求写入Cookies信息,则返回的Http如下,注意加粗的部分:
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=999&TestValue=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
三、Cookies高级知识
1.Cookie 的限制
大多数浏览器支持最大为 4096 字节的 Cookie。
浏览器还限制站点可以在用户计算机上存储的 Cookie 的数量。大多数浏览器只允许每个站点存储 20 个 Cookie;注 意这里的20个是指主键值,也就是20条Cookies记录,但是每个Cookies记录还可以包含若干子键,下面会详细解释。如果试图存储更多 Cookie,则最旧的 Cookie 便会被丢弃。有些浏览器还会对它们将接受的来自所有站点的 Cookie 总数作出绝对限制,通常为 300 个。
2.Cookies的存储格式
根据Netscape公司的规定,Cookie格式如下:
Set-Cookie: NAME=VALUE;Expires=DATE;Path=PATH;Domain=DOMAIN_NAME;SECURE
Cookies可以包含一个主键, 主键再包含子键。比如asp.net中获取Cookies的格式是:
Request.Cookies[key][subkey].ToString();
其中的key就是主键,subkey就是主键关联的子键。
(1)本地磁盘存储格式:
__utma
55197035.1760184385000514300.1215675318.1215675318.1215675318.1
17u.com/
1600
1907785472
30089218
2153600368
29942367
*
__utmz
55197035.1215675319.1.2.utmccn=(organic)|utmcsr=baidu|utmctr=%B9%B7%D2%A7%C2%C0%B6%B4%B1%F6+++|utmcmd=organic
17u.com/
1600
1015832320
29979080
2155320368
29942367
*具体的格式说明:
第1行是Cookie名称。
第2行是Cookie的值。
第3行是Cookie所属站点的地址。
第4行是个标记值。
第5行为过期时间的低位(时间为Windows下的FILETIME格式)。
第6行为过期时间的高位。
第7行为创建时间的低位。
第8行为创建时间的高位。
第9行总是为"*",Cookie记录分隔符(一个Cookies文件可以记录多个记录结构)。解析第一个结构后得到:
名称:__utma
值:55197035.1760184385000514300.1215675318.1215675318.1215675318.1
网址域名:17u.com
失效期:2010-7-10 15:35:18
修改日期:2008-7-10 15:35:18
(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.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一样关闭浏览器后则消失。在 asp.net中还可以通过设置HttpCookie对象的过期时间为DateTime.MinValue来指定此Cookies为跟随浏览器生效。(这句话来之不易啊,在脑袋等人的帮助下才查到的。)
如果设置了过期时间并且大于当前时间,则会保存Cookies值。
如果设置了过期时间但是小于等于当前时间,则清除Cookies值。
未设置Cookies过期时间时,cookies值是保存在浏览器内存空间中,故浏览器一旦关闭就未设置过期时间的cookies值会消失。
6.Cookies与Session
有时我们会忽略Cookies与Session的关系。但是两者是密不可分的。
Asp.net 一旦用户通过验证登录就会设置ASP.NET_SessionId值;
PHP 中用户打开浏览器后首次连接网站,就是获取一个PHPSESSID值,在整个过程不变,直到用户退出登录或关闭浏览器。
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,但是可以增加通过脚本直接获取的难度。
Microsoft Internet Explorer 版本 6 Service Pack 1 和更高版本支持 Cookie 属性 HttpOnly。
7.Cookies加密
在设置Cookies的属性时,有一个选项Secure用来控制Cookie的加密特性。
如果通过 SSL 连接 (HTTPS) 传输 Cookie,则为 true;否则为 false。默认为 false。
如果我们保存一个Cookies并设置加密,那么在非HTTPS的页面中,无论是使用javascript还是服务器端都无法获得此 Cookies。但是在本地依然可以看到此Cookies的存在。
8.Cookies与Ajax
如果Ajax请求访问一个服务器页面,此服务器页面是可以向用户浏览器写入Cookies和Session的。
四、使用Javascript和JQuery操作Cookies
在客户端我们同样需要操作Cookies。
(1)、使用javascript操作cookies.
1. // 说明:用 Javascript 操作 Cookie2. // 整理:http://www.CodeBit.cn3.
4. function getCookie( name ) {5. var start = document.cookie.indexOf( name + "=" );6. var len = start + name.length + 1;7. if ( ( !start ) && ( name != document.cookie.substring( 0, name.length ) ) ) {8. return null;9. }10. if ( start == -1 ) return null;11. var end = document.cookie.indexOf( ';', len );12. if ( end == -1 ) end = document.cookie.length;13. return unescape( document.cookie.substring( len, end ) );14. }15.
16. function setCookie( name, value, expires, path, domain, secure ) {17. var today = new Date();18. today.setTime( today.getTime() );19. if ( expires ) {20. expires = expires * 1000 * 60 * 60 * 24;21. }22. var expires_date = new Date( today.getTime() + (expires) );23. document.cookie = name+'='+escape( value ) +24. ( ( expires ) ? ';expires='+expires_date.toGMTString() : '' ) + //expires.toGMTString()25. ( ( path ) ? ';path=' + path : '' ) +26. ( ( domain ) ? ';domain=' + domain : '' ) +27. ( ( secure ) ? ';secure' : '' );28. }29.
30. function deleteCookie( name, path, domain ) {31. if ( getCookie( name ) ) document.cookie = name + '=' +32. ( ( path ) ? ';path=' + path : '') +33. ( ( domain ) ? ';domain=' + domain : '' ) +34. ';expires
(2)、使用Jquery操作Cookies
下面是封装了的专门用于操作Cookies的jQuery工具函数。、
当然此工具函数稍加修改,就可以变成标准的Javascript函数。
下载地址:https://files.cnblogs.com/zhangziqiu/jquery.extend-lastest.js
工具函数说明:
方法签名: jQuery.cookie(name, subName, value, options)
方法说明:读取、写入、删除Cookies
方法参数:
名称 |
说明 |
举例 |
name |
cookies的主键值 |
读取主键: $.cookie("singleKey")
$.cookie("singleKey", "", "singleKey-value", { expires: 1, path: "/", secure: false }) |
subName |
子键名称。在写入时请传递空或者null |
读取子键: $.cookie("multiKey", "subName1")
var subNameObj = { subName1: "aaa", subName2: "bbb", subName3: "ccc" }; $.cookie("multiKey", "", subNameObj, { expires: 1, path: "/", secure: false }); |
value |
Cookies值,可以是字符串或者对象。 |
参见上面实例。 |
options |
参数: |
指定过期时间: var myDate = new Date(); myDate.setFullYear(2009, 10, 10); $.cookie("singleKey", "", "singleKey-value", { expires: myDate, secure: false }) 1天后过期: var time = Date(); $.cookie("singleKey", "", "singleKey-value", { expires: 1, path: "/", secure: false }) |