搞开发都好几年了,突然有那么一天发现居然对cookie这个玩意是只知其然不知其所以然。 于是乎,发奋图强,找了一堆资料,深入研究了一番。这里,自己作了一下总结,列举出来,与大家共享。
\n
1. cookie为何物
\n
cookie实质上就是:网站存放在用户机器上的一小块文本信息。一旦浏览器接受到cookie,浏览器会把cookie的信息片段以”键/值”对的形式保存在本地.这以后, 当浏览器运行时,每次向同一服务器发送请求的时候,Web浏览器都会发送站点以前存储在本地的cookie.
\n
2. Cookie的成分
\n
name: 每个cookie由一个唯一的名称代表,这个名称可以包含字母、数字、下划线。cookie的名称是不分大小写,所以mycookie和MyCookie是一样。但考虑到服务器端语言可能区分大小写,建议定义和使用时还是区分大小写。
\n
value: 保存在cookie中的字符串值。这个值在存储之前必须使用encodeURIComponent()对其进行编码,以免丢失数据或占用了cookie。注意:cookie名字和值加起来的字节数不能超过4095字节,也即4KB。
\n
domain: 出于安全考虑,网站不能访问由其他域所创建的cookie。创建cookie以后,域的信息会作为cookie的一部分存储下来。关于域,这里给一个例子,如http://ibm.com/foo/index.aspx, 它的域为:ibm.com。
\n
path: cookie的另一个安全特征,限制对web服务器上特定目录的访问。即控制哪些访问能触发发送.例如请求的地址是上面的url,如果path=/foo,这个cookie就会被发送,但是path为其他的话,该cookie会被忽略。
\n
expires: cookie的过期时间。
\n
secure: 一个true/false值,用于表示cookie是否只能从安全网站(使用SSL和https协议的网站)中访问。如果这个值被设置为true
\n
3. cookie的读写流程
\n
浏览器对于Web服务器应答包头中Cookie的操作步骤:
\n
a. 从Web服务器的应答包头中提取所有的cookie。
\n
b. 解析这些cookie的组成部分(名称,值,路径等等)。
\n
c. 判定主机是否允许设置这些cookie。允许的话,则把这些cookie存储在本地。
\n
浏览器对Web服务器请求包头中所有的cookie进行筛选的步骤:
\n
a. 根据请求的url和本地存储cookie的属性,判断那些cookie能被发送给Web服务器。
\n
b. 对于多个cookie,判定发送的顺序。
c. 把需要发送的cookie加入到请求http包头中一起发送。
\n
4. 浏览器端对cookie的读写
\n
// Creates a cookie
\n
// sName: name
\n
// sValue: value
\n
// oExpires: expires date
\n
// sPath: path
\n
// sDomain: domain
\n
// bSecure: secure flag
\n
function setCookie(sName, sValue, oExpires, sPath, sDomain, bSecure, bHttpOnly) {
\n
var sCookie = sName + “=” + encodeURIComponent(sValue);
\n
if (oExpires) {
\n
sCookie += “; expires=” + oExpires.toGMTString();
\n
}
\n
if (sPath) {
\n
sCookie += “; path=” + sPath;
\n
}
\n
if (sDomain) {
\n
sCookie += “; domain=” + sDomain;
\n
}
\n
if (bSecure) {
\n
sCookie += “; secure”;
\n
}
\n
if (bHttpOnly){
\n
sCookie += “; httpOnly”;
\n
}
\n
document.cookie = sCookie;
\n
}
\n
// Get the value of a cookie by cookie name
\n
function getCookie(sName) {
\n
\n
var sRE = “(?:; )?” + sName + “=([^;]*);?”;
\n
var oRE = new RegExp(sRE);
\n
\n
if (oRE.test(document.cookie)) {
\n
return decodeURIComponent(RegExp["1"]);
\n
} else {
\n
return null;
\n
}
\n
}
\n
// delete cookie
\n
function deleteCookie(sName, sPath, sDomain) {
\n
var sCookie = sName + “=; expires=” + (new Date(0)).toGMTString();
\n
if (sPath) {
\n
sCookie += “; path=” + sPath;
\n
}
\n
if (sDomain) {
\n
sCookie += “; domain=” + sDomain;
\n
}
\n
document.cookie = sCookie;
\n
}
\n
调用方式:
\n
//set cookie in javascript
\n
function clientSetCookies(){
\n
//setCookie(“ClientCookie1″, “ClientTest1″, new Date(Date.parse(“May 4, 2009″)), “/CookieTest”, “http://localhost:6581/CookieApplication”, true);
\n
setCookie(“ClientCookie1″, “ClientTest1″, new Date(Date.parse(“May 4, 2009″)), null, null, false);
\n
setCookie(“ClientCookie2″, “ClientTest2″, new Date(Date.parse(“May 4, 2009″)));
\n
setCookie(“ClientCookie3″, “ClientTest3″);
\n
var sCookie = “The cookies created by client are:<br />{<br /> Client Cookie1: ” + getCookie(“ClientCookie1″)
\n
+ “<br /> Client Cookie2: ” + getCookie(“ClientCookie2″)
\n
+ “<br /> Client Cookie3: ” + getCookie(“ClientCookie3″)
\n
+ “<br />}”;
\n
document.getElementById(‘<% =divClient.ClientID%>’).innerHTML = sCookie;
\n
//deleteCookie(“cookie1″);
\n
//deleteCookie(“cookie2″);
\n
//deleteCookie(“cookie3″);
\n
}
\n
//get cookies which created by server
\n
function clientGetCookies(){
\n
var sCookie = “The cookies read by client and created by server are:<br />{<br /> Server Cookie1: ” + getCookie(“ServerCookie1″)
\n
+ “<br /> Server Cookie2: ” + getCookie(“ServerCookie2″)
\n
+ “<br /> Server Cookie3: ” + getCookie(“ServerCookie3″)
\n
+ “<br />}”;
\n
\n
document.getElementById(‘<% =divClient.ClientID%>’).innerHTML = sCookie;
\n
}
\n
5. 服务器端(Asp.net)对cookie的读写
\n
a. 读:
\n
divServer.InnerHtml = “The cookies read by Server and created by client are:<br />{<br /> Client Cookie1:”
\n
+ Request.Cookies["ClientCookie1"].Value + “<br /> Client Cookie2:”
\n
+ Request.Cookies["ClientCookie2"].Value + “<br /> Client Cookie3:”
\n
+ Request.Cookies["ClientCookie3"].Value + “<br />}”;
\n
b. 写:
\n
HttpCookie cookie1 = new HttpCookie(“ServerCookie1″, “serverTest1″);
\n
HttpCookie cookie2 = new HttpCookie(“ServerCookie2″, “serverTest2″);
\n
HttpCookie cookie3 = new HttpCookie(“ServerCookie3″, “serverTest3″);
\n
Response.Cookies.Add(cookie1);
\n
Response.Cookies.Add(cookie2);
\n
Response.Cookies.Add(cookie3);
\n
divServer.InnerHtml = “The cookies created by server are:<br />{<br /> Server Cookie1:”
\n
+ Request.Cookies["ServerCookie1"].Value + “<br /> Server Cookie2:”
\n
+ Request.Cookies["ServerCookie2"].Value + “<br /> Server Cookie3:”
\n
+ Request.Cookies["ServerCookie3"].Value + “<br />}”;
\n
6. 关于Cookie的用途
\n
防止网上重复投票;
通过cookie实现自动登陆
单点登陆 ( Single Sign On, SSO),是目前比较流行的企业业务整合的解决方案之一. 简单的说, 就是每个客户端对每个网站同时只能打开一个. 这样最大的好处是可以缓解服务器的压力. 一般在企业网站中较为常见. 因为门户网站、社区博客等希望你打开的越多越好, 不会设置单点登录,但163邮箱是个例外。
\n
这3个应用,原理也很简单,大抵有2种方案,如下:
\n
1.前台Js检查应用cookie
\n
function setHistory(){
\n
if(getCookie(“HistoryCookie”) == null){
\n
setCookie(“HistoryCookie”, “I’ve come here.”, new Date(Date.parse(“May 4, 2009″)));
\n
}
\n
else{
\n
//alert(“welcome!”);
\n
}
\n
}
\n
function setHistory(){
\n
if(getCookie(“HistoryCookie”) == null){
\n
setCookie(“HistoryCookie”, “I’ve come here.”, new Date(Date.parse(“May 4, 2009″)));
\n
}
\n
}
\n
\n
2. 服务器端检查应用cookie
\n
if (Request.Cookies["HistoryCookie"] != null && !string.IsNullOrEmpty(Request.Cookies["HistoryCookie"].Value))
\n
{
\n
divHistory.InnerHtml = “You have come here before!”;
\n
}
\n
else
\n
{
\n
}
\n
\n
这2种方案可以单独使用,也可以结合使用。但存在一个共同的缺陷是:如果客户端禁用了cookie或者删除了cookie,就达不到预期目标。
\n
7. Cookie的安全
\n
请参阅:http://www.cnblogs.com/qiantuwuliang/archive/2009/03/09/1406727.html
\n
8. 关于Asp.net中2个看似相同的cookie类:System.Web.HttpCookie和 System.Net.Cookie 的详细分析比较,请参阅:
\n
http://www.cnblogs.com/downmoon/archive/2008/09/11/1289298.html
\n
9. 其他参考:
\n
http://www.cnblogs.com/ziyifly/archive/2008/09/20/1294922.html
\n
JavaScript高级编程
\n
10. 本文源码下载
\n\n