参考:《JavaScript 高级程序设计》(第3版)扩展:
扩展:
数据存储(二)WebStorage 之 sessionStorage、globalStorage、localStorage_不头秃的码农的博客-CSDN博客
1. 背景
cookie 最初由网景公司创造,解决将数据存储在客户端上的问题。
Persistent Client State: HTTP Cookies(持久客户端状态:HTTP Cookies)的标准中对 cookie 进行了阐述,链接 => Client Side State - HTTP Cookies
2. 解释
用来在客户端存储会话信息,以及和服务端进行通信。
HTTP Cookie 标准要求服务器对任意HTTP请求发送 Set-Cookie 响应头,其中包含会话信息。
- 响应头 Set-Cookie: name=value
浏览器接收到之后,把会话信息存储下来,并通过为每个请求添加 Cookie 请求头将信息发送回服务器。
- 请求头 Cookie: name=value
3. cookie 结构
部分 | 描述 | 关键字 |
名称 | 唯一确定cookie的名称。cookie名称不区分大小写。需要被URL编码。 | |
值 | 存储在cookie中的字符串值。需要被URL编码。 | |
域 | cookie对于哪个域是有效的。所有向该域发送的请求中都会包含这个cookie信息。 例如:domain=.wrox.com; | domain= |
路径 | 访问指定域中哪个路径可以发送cookie。 例如:指定path=http://www.wrox.com/books/; 则只有http://www.wrox.com/books这个路径下的请求会携带cookie,http://www.wrox.com不会携带。 | path= |
失效时间 | 表示cookie何时被删除,何时不会向服务器发送。值是GMT格式的日期。 例如:expires=Mon, 01-Jan-22 01:01:01 GMT; | expires= |
安全标志 | 指定后,cookies只有在使用SSL链接时才发送到服务器。 | secure |
以上每一段信息都作为 Set-Cookie 的一部分,使用分号加空格,分隔每一段,如下:
Set-Cookie: name=value; expires=Mon, 01-Jan-22 01:01:01 GMT; domain=.wrox.com; path=/; secure
以上信息头指定了一个叫name的cookie,它会在格林威治时间2022年1月1日 01:01:01 失效,同时对于wrox.com的任何子域都有效,但协议需要是https。
子cookie
为了绕开浏览器单域名下cookie数量限制,可以使用子cookie(subcookie)的概念来更加结构化的存储数据。
常见格式如下:name1=value1&name2=value2
4. cookie 限制
限制 | 描述 | 意义 | 解决 |
1. 同源且不能跨会话 | cookie在性质上是绑定在特定域名下的。当设定了一个cookie之后,再给创建它的域名发送请求时,都会包含这个cookie。 | 确保cookie不被恶意使用。(存储在cookie中的信息只能让批准的接受者访问,无法被其他域访问) | 需要跨会话存储信息,使用LocalStorage |
2. Cookie 总数有限 | ① 不同浏览器对总数的限制不同: • Safari和Chrome没有硬性规定; • IE7之前,每个域名最多20个; • IE7及以上版本和Firefox,每个域名最多50个; • Oprea,每个域名最多30个; ② 当超过限制后,继续设置cookie,浏览器会清除之前的cookie: • IE和Opera会删除最近最少使用过的cookie • FireFox随机清除 | 确保不占用过多的内存或磁盘空间 | 可采用子cookie的形式存储 |
3. Cookie 尺寸有限 | ① 尺寸限制为 4096B(加减1)。 尺寸限制影响到一个域下所有的cookie,并非每个域单独设置。 ② 当创建超过最大尺寸的cookie,该cookie会被丢弃。 | 确保不占用过多的内存或磁盘空间 | 将长度限制在4095B之内 |
4. 需要URL编码 | cookie的名称和值必须经过URL编码,使用时也需要URL解码。 | 服务器在接收字符串时,不允许空格和特殊字符等。为避免邮箱等带有特殊字符的传不过去,需要编码。 | 编码: encodeURIComponent() 解码: decodeURIComponent() |
5. cookie 存储的位置
内存是临时存储(内存决定电脑能同时运行多少程序);
硬盘是长久存储(硬盘决定电脑能存放多少东西);
如果cookie有过期时间,就会被存储于硬盘中,过期后删除;
如果cookie没设置过期时间,就会被存储于内存中,会话结束时失效;
6. JavaScript中控制cookie
document.cookie 可用来获取、设置cookie。
/**
* cookie的写入、读取、删除工具
*/
var CookieUtil = {
get: function (name) {
let cookieName = encodeURIComponent(name) + "=",
cookieStart = document.cookie.indexOf(cookieName),
cookieValue = null;
if (cookieStart > -1) {
let 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) {
let 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";
}
document.cookie = cookieText;
},
unset: function (name, path, domain, secure) {
this.set(name, "", new Date(0), path, domain, secure);
},
};
// 调用
// 设置cookie
CookieUtil.set("name", "不头秃的码农");
CookieUtil.set(
"book",
"JavaScript",
new Date("2022.11.30"),
"/",
"baidu.com",
true
);
// 读取cookie
console.log(CookieUtil.get("name"));
console.log(CookieUtil.get("book"));
// 删除cookie
CookieUtil.unset("name")
CookieUtil.unset("book")
7. 总结
由于所有的 cookie 都会由浏览器作为请求头发送,如果在 cookie 中存储大量的信息会影响特定域名的请求性能。cookie 信息越大,完成对服务器请求的时间就越长。再考虑到 cookie 有数量和大小的限制,所以尽可能少在 cookie 中存储信息。
不要在cookie中存储重要和敏感的隐私数据,cookie数据并非存储在一个安全环境中,其中包含的任何数据都可以被他人访问。