客户端存储
Cookies sessionStorage localStorage
从以下6个方面分析客户端存储的差异
- 使用方式
- 存储限制
- 生命周期
- 作用域
- 访问限制
- 安全
1. 使用方式
1.1. Cookies
// 服务端
// Set-Cookie: <cookie名>=<cookie值>
// 浏览器
document.cookie = "yummy_cookie=choco";
// Cookies的库
var docCookies = {
getItem: function (sKey) {
return decodeURIComponent(document.cookie.replace(new RegExp("(?:(?:^|.*;)\\s*" + encodeURIComponent(sKey).replace(/[-.+*]/g, "\\$&") + "\\s*\\=\\s*([^;]*).*$)|^.*$"), "$1")) || null;
},
setItem: function (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;
},
removeItem: function (sKey, sPath, sDomain) {
if (!sKey || !this.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;
},
hasItem: function (sKey) {
return (new RegExp("(?:^|;\\s*)" + encodeURIComponent(sKey).replace(/[-.+*]/g, "\\$&") + "\\s*\\=")).test(document.cookie);
},
keys: /* optional method: you can safely remove it! */ function () {
var aKeys = document.cookie.replace(/((?:^|\s*;)[^\=]+)(?=;|$)|^\s*|\s*(?:\=[^;]*)?(?:\1|$)/g, "").split(/\s*(?:\=[^;]*)?;\s*/);
for (var nIdx = 0; nIdx < aKeys.length; nIdx++) { aKeys[nIdx] = decodeURIComponent(aKeys[nIdx]); }
return aKeys;
}
};
1.2. Storage
作为 Web Storage API 的接口,Storage 提供了访问特定域名下的会话存储
或本地存储
的功能
如果你想要操作一个域名的会话存储,可以使用 Window.sessionStorage
;
如果想要操作一个域名的本地存储,可以使用 Window.localStorage
。
// 抽象类
abstract class Storage {
length // readonly 存储在 Storage 对象中的数据项数量
key() {
// 该方法接受一个数值 n 作为参数,并返回存储中的第 n 个键名
}
getItem() {
// 获取
}
setItem() {
// 设置
}
removeItem() {
// 移除
}
clear() {
// 删除所有
}
}
class sessionStorage extends Storage {
}
class localStorage extends Storage {
}
2. 存储限制
Cookie 4K
storage 每个源的存储大小将限制在10M
3. 生命周期
Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT;
- 会话期 Cookie: 没有设置Expires 和 Max-Age,仅在会话期内有效
- 持久性 Cookie: 取决于过期时间(Expires)或有效期(Max-Age)
- sessionStorage: 当会话结束(当前页面关闭的时候,自动销毁)
- localStorage: 没有时间限制
4. 作用域
4.1. Cookie
Domain 和 Path 标识定义了Cookie的作用域:即允许 Cookie 应该发送给哪些URL
Domian: 指定了哪些主机可以接受 Cookie
Path 标识指定了主机下的哪些路径可以接受 Cookie
SameSite: SameSite Cookie 允许服务器要求某个 cookie 在跨站请求时不会被发送
Cookie prefixes:
5. 访问限制
Secure HttpOnly
- Secure: 标记为 Secure 的 Cookie 只应通过被 HTTPS 协议加密过的请求发送给服务端
- HttpOnly: JavaScript Document.cookie API 无法访问带有 HttpOnly 属性的cookie
通过 Document.cookie 属性可访问 此方法新建的 Cookie 和 非httpOnly的Cookie
通过 JavaScript 创建的 Cookie 不能包含 HttpOnly 标志
storage :同源策略的限制
6. 安全
- HttpOnly:禁止javascript获取Cookie,防止XSS攻击
- SameSite Cookie:禁止跨域获取Cookie,防止跨站请求伪造(CSRF)
- 减少Cookie有效期