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