Cookie
最初是在客户端用于存储会话信息的。
限制
cookie在性质上是绑定在特定的域名下的。当设置了一个cookie后,在给创建它的域名发送请求的时候,都会包含这个cookie。这个限制确保了存储在cookie中的信息只能让批准的接受者访问,不能让其他域访问。
每个域的cookie总数是有限制的,不同浏览器的限制不同:
- IE6之前 最多20个
- IE7之后 最多50个
- Firefox 最多50个
- OPera 最多30个
- Safari和Chrome没有硬性规定
当超过单个域名的限制后,还要在设置cookie,浏览器就会清除以前的cookie。IE和Opear会删除最近最少使用的cookie,Firefox看上去好像是随机删除的
浏览器中对于cookie的尺寸也有限制。大多浏览器约有4096B(±1)的限制。为了最佳的浏览器兼容性,最好将整个cookie的大小限制在4095B内,尺寸限制影响到一个域的所有cookie,并不是每个cookie都单独设置。尝试创建超过最大尺寸限制的cookie,那么该cookie会悄无声息的被丢掉。
构成
cookie由浏览器保存的以下几块信息构成:
名称
一个唯一确定 cookie的名称。cookie名称是不区分大小写的。但是在实践中还是应该把cookie的名称看成是区分大小写的,因为某些服务器会这样处理cookie cookie的名称必须经过URL编码的。值
存储在cookie中的字符串值。值必须被URL编码域
cookie对于哪个域是有效的,所有向该域发送的请求中都会包含这个cookie信息。这个值可以包含子域,也可以不包含子域。如果没有明确的规定,那么这个域会被认作来设置cookie的那个域。路径
对于指定域中的那个路径,应该响服务器发送cookie。例如可以指定cookie只能从http://www.xxx.xxx.com/xxx中才能访问,那么http://www.xxx.xxx.com的页面就不会发送cookie信息,即使请求都是来自同一个域的。失效时间
表示cookie何时应该被删除的时间戳(也就是,何时应该停止向服务器发送这个cookie)。默认情况下,浏览器会话结束时即将所有cookie删除;不过也可以自己设置删除的时间。但是设置的时间如果是当前时间以前的时间,那么这个cookie会被立即删除。安全标志
指定后,cookie只有在使用SSL链接的时候才发送到服务器。secure是cookie中唯一一个非名值对儿的部分。
javaScript中的cookie
var CookieUtil = {
get:function(name) {
var cookieName = encodeURIComponent(name) + "=",
cookieStart = document.cookie.indexOf(cookieName),
cookieValue = null;
if (cookieStart > -1) {
var 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) {
var cookieText = encodeURIComponent(name) + "=" + encodeURIComponent(value);
if(expires instanceof Data) {
cookieText += "; expires=" + expires.toGMTString();
}
if(path) {
cookieText += "; path=" + path;
}
if(domain) {
cookieText += "; domain=" + domain;
}
if(secure) {
cookieText += "; secure";
}
document.cookie = cookieText;
},
unset:function(name, path, domain, secure) {
this.set(name, " ", new Date(0), path, domain, secure);
}
};
sessionStorage
sessionStorage对象存储特定于某个会话的数据,也就是该数据只保持到浏览器关闭。这个对象就像会话cookie,也会在浏览器关闭后消失。存储在sessionStorage的数据可以跨越页面刷新而存在。
- 存储数据
- 使用方法存储数据
sessionStorage.setItem(“name”, ‘“value”); - 使用属性存储数据
sessionStorage.book = “value”;
- 使用方法存储数据
不同浏览器写入数据的方式有所不同,Firefox和Webkit实现了同步写入,所以添加到存储空间中的数据是立刻被提交的。而IE的实现则是异步写入数据,所以在设置数据和将数据实际写入磁盘之间可能有一些延时。
在IE8中可以强制把数据写入磁盘,在设置新的数据之前使用beign()方法,并且在所有设置完成之后调用commit()方法
//只是用与IE8
sessionStorage.begin();
sessionStorage.name = 'name';
sessionStorage.book = 'value';
sessionStorage.commit();
上面这段代码确保了name和book的值在调用commit()之后立刻被写入磁盘。调用begin()方法是为了这段代码执行的时候不会发生磁盘写入的操作。
读取数据
- 使用方法读取数据
var name = sessionStorage.getItem(“name”); - 使用属性读取数据
var book = sessionStorage.book; - 结合length属性和key()方法类迭代sessionStorage的值
for ( var i = 0, len = sessionStorage.length; i < len; i++) {
var key = sessionStorage.key(i);
var value = sessionStorage.getItem(key);
console.log( key + “=” + value);
}
- 使用方法读取数据
删除数据
- 使用delete删除一个值(在Webkit中无效)
delete sessionStorage.name; - 使用方法删除一个值
sessionStorage.removeItem(‘book’);
- 使用delete删除一个值(在Webkit中无效)
sessionStorage对象应该主要用于仅针对会话的小段数据的存储,如果需要跨越会话存储数据,那么globalStorage或者localStorage更为合适。
globalStorage
这个对象的目的是跨越会话存储数据,但有特定的访问限制。要使用globalStorage,首先要指定哪些域可以访问该数据。可以通过方括号标记使用属性来实现,如下所示
保存数据
globalStorage[“xxx.com”].name = “value”;获取数据
var name = globalStorage[“xxx.com”].name;
对于globalStorage的空间访问,是依据发起请求的页面的域名、协议和端口号来限制的。例如,如果使用了HTTPS协议在xxx.com中存储了数据,那么通过HTTP访问的xxx.com的页面就不能访问该数据。同样,通过80端口访问的页面则无法与同一个域同样协议但是端口不同的页面共享数据。类似于Ajax请求的同源策略。
globalStorage的每个睡属性都是Storage的实例。因此,可以像下面这样使用:
globalStorage["www.xxx.com"].name = "value";
globalStorage["www.xxx.com"].book = "value";
globalStorage["www.xxx.com"].removeItem("name");
var book = globalStorage["www.xxx.com"].getItem("book");
如果事先不能确定域名,那么使用location.host作为属性名比较安全。例如:
globalStorage[location.host].name = “value”;
var book = globalStorage[location.host].getItem(“book”);
如果不使用removeItem()或者delete删除,或者用户未清除浏览器的缓存,那么存储在globalStorage属性中的数据会一直保留在磁盘上。这让globalStorage非常适合在客户端存储文档会长期保存用户偏好设置。
localStorage
与globalStorage不同,不能给localStorage指定任何访问规则,规则事先就设定好了,要访问一个localStorage对象,页面必须来自同一个域名(子域名无效),使用同一种协议,在同一个端口上。
由于localStorage是Storage的实例,所以可以像使用sessionStorage一样来使用。
function saveToLocal(id, key, value) {
let name = window.localStorage.__name__;
if (!name) {
name = {};
name[id] = {};
} else {
name = JSON.parse(name);
if (!name[id]) {
name[id] = {};
}
}
name[id][key] = value;
window.localStorage.__name__ = JSON.stringify(name);
};
function loadFromLocal(id, key, def) {
let name = window.localStorage.__name__;
if (!name) {
return def;
}
name = JSON.parse(name)[id];
if (!name) {
return def;
}
let ret = name[key];
return ret || def;
};
大多数浏览器对localStorage的限制在5MB,chrome和移动端限制在2.5MB.