本来只是想简单看看 cookie、localStorage 和 sessionStorage 的,没想到一搜索扩展了很多知识。中心主题集中在 web storage (localStorage, sessionStorage) 的认识上,以及怎么使用它们。不过,在此之前,先来认识一下小小的 cookie 吧。
其实,除了经常讨论到的 cookie、localStorage 和 sessionStorage 外,还有 IE 独有的 userData,几乎已经淘汰的 Flash(现在有 HTML5 啦),Firefox 独有的 globalStorage(Firefox13 开始不再支持),以及 Google Gears SQLite(需要安装像 Flash 那样的插件)。这么看来,只有标准化、通用化的技术才能经住考验,得以广泛延续推广使用。
那今天就来好好看看历史悠久的 cookie 吧 ,学以致用!
Cookie 简介
在没有 web storage 之前,是通过 cookie 在客户端存储会话信息的。它的大小通常限制为 4093 bytes (不同浏览器会有所区别),因此不适合大量数据的存储。这种技术是在 1993 年 Netscape 的 Lou Montulli 为了提高用户的访问速度发明的。
当用户通过 HTTP 协议访问一个服务器时,这个服务器会将一些 key/value 键值返回客户端,并给这些数据加上一些限制条件,符合条件的用户下次访问该服务器时,这些数据又被完整地返回给服务器。所以 cookie 是在客户端和服务器间来回传递的,通过 HTTP 的 Set-Cookie
响应头部设置。例如:
HTTP/1.1 200 OK
Content-type: text/html
Set-Cookie: page_loaded=25; Expires=Wed, 09 Jun 2021 10:18:14 GMT
这里,浏览器接收到表明回应成功的 HTTP 200 代码,以及回应的内容类型,通过 Set-Cookie
头部创建了一个 cookie:
Name | Value | Expires |
page_loaded | 25 | Wed, 09 Jun 2021 10:18:14 GMT |
除非在 Wed, 09 Jun 2021 10:18:14 GMT
之前刷新,否则该 cookie 将在这时间之后无效并被客户端移除。如果它没有被移除,将来所有的来自该网站(cookie 在性质上是绑定在特定的域名下的)的请求中都将携带类似的响应头部:
GET /index.html HTTP/1.1
Host: www.example.com
Cookie: page_loaded=25;
cookie 优点
简单:cookie 是基于文本的轻量结构,用简单的键值对即可定义
可配置到期规则:cookie 可以在客户端会话结束时到期,也可以在客户端计算机上无限期存储,取决于客户端的到期规则
数据持久性:虽然客户端上的 cookie 保留时间取决于客户端上的到期规则以及用户干预,但 cookie 通常是客户端上持续时间最长的数据保存形式
不需要任何服务器资源:cookie 是存储在客户端上,由客户端发送后再由服务器读取
cookie 缺点
数量和长度限制:每个域的 cookie 总数是有限的。IE6 或更低版本最多有 20 个 cookie;IE7 和之后的版本最多有 50 个;Firefox 最多有 50 个;Chrome 和 Safari 没作硬性限制,而单个 cookie 最多 4093 bytes,超出部分会被截掉。具体浏览器的限制可参考 Iain Roberts 的测试。
安全性:潜在隐私和安全影响方面,cookie 一直有个坏名声。他们很容易受到安全问题攻击影响,例如关键攻击载体的 CSRF (Cross Site Request Forgery),XSS (Cross Site Scripting Attacks) 以及 Session Hijacking 。cookie 把所有要保存的数据通过 HTTP 协议的头部在客户端和服务器端来回传递,所有的数据都存储在客户端里,所以这些 cookie 数据可以被轻松访问到,如果 cookie 被人拦截了,那人就可以取得所有的信息。即使加密也与事无补,因为拦截者并不需要知道 cookie 的意义,他只要原样转发 cookie 就可以达到目的了
性能问题:由于每次请求都会携带 cookie 信息,所以在 cookie 中大量存储信息会影响特定域的请求性能
JavaScript 管理 cookie
在 JavaScript 中,可以通过 document.cookie
来操作 cookie 对象。例如,可用以下代码遍历 cookie:
if (document.cookie) {
var cookies = document.cookie.split(";");
var info = '';
for (var i = 0; i < cookies.length; i++) {
var aCookie = cookies[i].split("=");
info += (aCookie[0] + " = " + aCookie[1] + '\n');
}
console.log('cookie info:\n\n' + info);
} else {
console.log('no cookie exist')
}
另外,cookie 还有一些属性可以设置:
expires 属性:该属性指定了 cookie 的生存期,默认情况下 cookie 是暂时存储的,只在客户端会话期间存在,用户退出后这些值就丢失了。如果想让 cookie 存在一段时间,就要用 expires
属性设置一个未来过期的时间。
path 属性:它指定与 cookie 关联在一起的网页。默认情况下,cookie 会与创建它的网页、该网页处于同一目录下的网页以及与其子目录下的网页关联。
domain 属性:domain
属性可使多个 web 服务器共享 cookie,但不能将一个 cookie 的域设置成服务器所在域之外的域。
secure 属性:它是一个布尔值,指定在网络上如何传输 cookie。默认是不安全的,通过一个普通的 HTTP 连接传输。
例如,可通过以下方法设置一个 cookie:
function setCookie(cname, cvalue, exdays) {
var d = new Date();
d.setTime(d.getTime() + (exdays*24*60*60*1000));
var expires = "expires="+ d.toUTCString();
document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/";
}
更多的例子可参见 w3schools 的 JavaScript Cookies。
好了,先说到这里,下次继续 web storage 的话题。