HTTP Cookie, 一般直接叫作cookie,最初是在客户端用于存储会话信息的。该标准要求服务器对任意HTTP请求发送Set-Cookie HTTP头做为响应的一部分,其中包含会话信息。这个HTTP响应设置一个以name为名称、以value为值的cookie,名称和值在传送时都必须是URI编码的。浏览器会存储这样的会话信息,并在这以后,经过为每一个请求添加Cookie HTTP头将信息发送回服务器,发送回服务器的额外信息能够用于惟一验证客户端来自于发送的哪一个请求。web
cookie在性质上是绑定在特定的域名下的。当设定了一个cookie后,再给建立它的域名发送请求时,都会包含这个cookie。这个限制确保了存储在cookie中的信息只能让批准的接受者访问,而没法被其余域访问。浏览器
IE6及更低的版本每一个域名限制为20个cookie,IE7及之后的版本每一个域名限制为50个cookie。安全
Firefox每一个域名cookie限制为50个。服务器
Opera每一个域名cookie限制为30个。cookie
Safari和Chrome对每一个域的cookie的数量限制没有硬性规定dom
大多数浏览器对每一个cookie有大约4096B的长度限制(大约4K)性能
cookie由浏览器保存的如下几块信息构成网站
名称this
值编码
域:cookie对哪一个域是有效的,全部向该域发送的请求中都会包含这个cookie信息,默认值为设置cookie的那个域
路径:指定域中的哪一个路径,应该向服务器发送cookie。例如指定该值为http://www.example.com/test1/
,则只有该路径下的请求会包含这个cookie
失效时间: cookie什么时候应该被删除的时间戳
安全标志: 指定后,cookie只有在使用SSL链接时,才会发送到服务器
尤为要注意,域、路径、失效时间、安全标志都是服务器给浏览器的标识,这些参数并不会做为发送到服务器的cookie信息的一部分,只有键值对才会被发送。
使用document.cookie
能够获取当前页面可用的全部的cookie组成的字符串,该字符串是有分号隔开的键值对构成(由分号隔开的一个键值对就是一个cookie),例如:name1=value1;name2=value2;name3=value3
。全部名字和值都是通过URL编码,因此必须使用decodeURIComponent()来解码。
当document.cookie
用于设置值的时候,document.cookie
属性能够设置为一个新的字符串,这个cookie字符串会被解释并添加到现有的cookie集合中。设置document.cookie
并不会覆盖cookie,除非设置的cookie的名称已经存在
var CookieUtil = { get: function(name){ var cookieName = encodeURIComponent(name) + '=', cookieStart = document.cookie.indexOf(cookieName), cookieValue = null; if(cookieStart > -1){ cookieEnd = document.cookie.indexOf(';', cookieStart); if(cookieEnd == -1){ cookieEnd = document.cookie.length; } cookieValue = decodeURIComponent(document.cookie.substring(cookieStart+cookieName.length, cookieEnd)); } return cookieValue; }, set: function(name, value, expires, path, domain, secure){ // 设置的cookie的名称已存在,将会覆盖原有的cookie var cookieText = encodeURIComponent(name) + '=' + encodeURIComponent(value); if(expires instanceof Date){ cookieText += "; expires=" + expires.toGMTString(); } if(path){ cookieText += "; path=" + path; } if(domain){ cookieText += "; domain=" + domain; } if(secure){ cookieText += "; secure=" + secure; } document.cookie = cookieText; }, // 删除已有cookie unset: function(name, path, domain, secure){ this.set(name, "", new Date(), path, domain, secure); } }
为了绕开浏览器的单域名下的cookie数量限制,能够在每一个cookie中存放多个更小的字段(子cookie)。子cookie最多见的格式以下:
'name=name1=value1&name2=value2&name3=value3'
子cookie通常也以查询字符串的格式进行格式化。而后这些值可使用单个cookie进行存储和访问,而非对每一个键值对使用不一样的cookie存储。最后网站或web应用程序能够无需达到单域名cookie上限也能够存储更加结构化的数据。为了更好地操做子cookie,必须创建一系列新方法。子cookie的解析和序列化会因子cookie的指望用途而略有不一样并更加复杂些。
var SubCookieUtil = { get: function(name, subName){ var subCookies = this.getAll(name) if(subCookies){ return subCookies[subName]; } else { return null; } }, getAll: function(name){ var cookieName = encodeURIComponent(name) + "=", cookieStart = document.cookie.indexOf(cookieName), cookieValue = null, cookieEnd, subCookie, i, parts, result = {}; if(cookeStart > -1){ cookieEnd = document.cookie.indexOf(";", cookieStart); if(cookieEnd == -1){ cookieEnd = document.cookie.length; } cookieValue = document.cookie.substring(cookieStart+cookieName.length, cookieEnd); if(cookieValue.length>0){ subCookies = cookieValue.split("&"); for(i=0, len=subCookies.length; i<len;i++){ parts = subCookies[i].split("="); result[decodeURIComponent(parts[0])] = decodeURIComponent(parts[1]); } return result; } } return null; }, set: function(name, subName, value, expires, path, domain, secure){ var subcookies = this.getAll(name)||{}; subcookies[subName] = value; this.setAll(name, subcookies, expires, path, domain, secure); }, setAll: function(name, subcookies, expires, path, domain, secure){ var cookieText = encodeURIComponent(name) + "=", subcookieParts = new Array(), subName; for(subName in subcookies){ if(subName.length >0 && subcookies.hasOwnProperty(subName)){ subcookieParts.push(encodeURIComponent(subName) + "=" + encodeURIComponent(subcookies[subName]); } } if(cookieParts.length >0){ cookieText += subcookieParts.join("&"); if(expires instanceof Date){ cookieText += "; expires=" + expires.toGMTSting(); } if(path){ cookieText += "; path=" + path; } if(domain){ cookieText += "; domain=" + domain; } if(secure){ cookieText += "; secure=" + secure; } } else { cookieText += "; expires="+(newDate(0)).toGMTString(); } document.cookie = cookieText; }, unset: function(name, subName, path, domain, secure){ var subcookies = this.getAll(name); if(subcookies){ delete subcookies[subName]; this.set(name, subcookies, null, path, domain, secure); } }, unsetAll: function(name, path, domain, secure){ this.setAll(name, null, new Date(0), path, domain, secure); } };
操做cookie的时候须要密切关注cookie的长度,以防超过单个cookie的长度限制
全部的cookie都会由浏览器做为请求内容的一部分发送,因此在cookie中存储大量信息会影响到特定域的请求性能。cookie越大,完成对服务器请求的时间就越长。尽管浏览器对cookie进行了大小限制,不过最好仍是尽量在cookie中少存储信息,以免影响性能。
cookie的性质和局限性使其并不能做为存储大量信息的理想手段。