Storage

由于HTTP的无状态性,不通过额外的手段,服务器不知道用户上一次做了什么,所以Cookie就是用来绕开HTTP的无状态性的“额外手段”之一。服务器可以设置或读取Cookies中包含信息,借此维护用户跟服务器会话中的状态。Cookie会在每次发送HTTP请求时附加到Cookie请求头字段, 服务器以此来进行会话跟踪。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
/*!
* https://developer.mozilla.org/en-US/docs/Web/API/document.cookie
* https://github.com/madmurphy/cookies.js
*/
(function (root, factory) {

if (typeof(Namespace) === 'undefined') {
Namespace = {};
}

/**
* 声明一个全局变量用来注册命名空间
* @namespace Namespace
*/
Namespace.register = function (namespace) {
var nsArr = namespace.split('.');
var nsStr = '', codeStr = '';
nsArr.forEach(function (ns, idx) {
nsStr += (idx === 0 ? ns : '.' + ns);
codeStr += 'if (typeof(' + nsStr + ') === "undefined") { ' + nsStr + ' = {}; }';
});
codeStr && eval(codeStr);
};

factory(root.Namespace);

})(window, function (Namespace) {

/**
* 注册[cookieStorage]命名空间
* @namespace cookieStorage
*/
Namespace.register('cookieStorage');

cookieStorage.setItem = setItem;
cookieStorage.getItem = getItem;
cookieStorage.removeItem = removeItem;

function setItem(sKey, sValue, vEnd, sPath, sDomain, bSecure) {
if (!sKey || /^(?:expires|max\-age|path|domain|secure)$/i.test(sKey)) {
return false;
}
var sExpires = "";
if (vEnd) {
switch (vEnd.constructor) {
case Number:
sExpires = vEnd === Infinity ? "; expires=Fri, 31 Dec 9999 23:59:59 GMT" : "; max-age=" + vEnd;
break;
case String:
sExpires = "; expires=" + vEnd;
break;
case Date:
sExpires = "; expires=" + vEnd.toUTCString();
break;
}
}
document.cookie = encodeURIComponent(sKey) + "=" + encodeURIComponent(sValue) + sExpires + (sDomain ? "; domain=" + sDomain : "") + (sPath ? "; path=" + sPath : "") + (bSecure ? "; secure" : "");
return true;
}

function getItem(sKey) {
if (!sKey) {
return null;
}
return decodeURIComponent(document.cookie.replace(new RegExp("(?:(?:^|.*;)\\s*" + encodeURIComponent(sKey).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=\\s*([^;]*).*$)|^.*$"), "$1")) || null;
}

function removeItem(sKey, sPath, sDomain) {
if (!hasItem(sKey)) {
return false;
}
document.cookie = encodeURIComponent(sKey) + "=; expires=Thu, 01 Jan 1970 00:00:00 GMT" + (sDomain ? "; domain=" + sDomain : "") + (sPath ? "; path=" + sPath : "");
return true;
}

function hasItem(sKey) {
if (!sKey || /^(?:expires|max\-age|path|domain|secure)$/i.test(sKey)) {
return false;
}
return (new RegExp("(?:^|;\\s*)" + encodeURIComponent(sKey).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=")).test(document.cookie);
}

});

sessionStorage

sessionStorage 属性允许你访问一个 session Storage 对象。它与 localStorage 相似,不同之处在于 localStorage 里面存储的数据没有过期时间设置,而存储在 sessionStorage 里面的数据在页面会话结束时会被清除。页面会话在浏览器打开期间一直保持,并且重新加载或恢复页面仍会保持原来的页面会话。在新标签或窗口打开一个页面会初始化一个新的会话。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
(function () {

// listen for changes to localStorage
if (window.addEventListener) {
window.addEventListener('storage', storageEventListener, false);
} else {
window.attachEvent('onstorage', storageEventListener);
}

// Ask other tabs for session storage (this is ONLY to trigger event)
if (!sessionStorage.length) {
localStorage.setItem('getSessionStorage', Date.now());
localStorage.removeItem('getSessionStorage');
}

// transfers sessionStorage from one tab to another
function storageEventListener(event) {
if (!event) {
event = window.event;
}
if (!event.newValue) {
// do nothing if no value to work with
return;
}
if (event.key == 'getSessionStorage') {
// another tab asked for the sessionStorage -> send it
localStorage.setItem('sessionStorage', JSON.stringify(sessionStorage));
// the other tab should now have it, so we're done with it.
localStorage.removeItem('sessionStorage'); // <- could do short timeout as well.
} else if (event.key == 'sessionStorage' && !sessionStorage.length) {
// another tab sent data <- get it
var data = JSON.parse(event.newValue);
for (var key in data) {
if (data.hasOwnProperty(key)) {
sessionStorage.setItem(key, data[key]);
}
}
}
}

})();

localStorage

localStorage 属性允许你访问一个 local Storage 对象。localStorage 与 sessionStorage 相似。不同之处在于,存储在 localStorage 里面的数据没有过期时间(expiration time),而存储在 sessionStorage 里面的数据会在浏览器会话(browsing session)结束时被清除,即浏览器关闭时。