JS 本地数据存储之 cookie - JS 学习笔记

JS 本地数据存储之 cookie - JS 学习笔记

本来只是想简单看看 cookie、localStorage 和 sessionStorage 的,没想到一搜索扩展了很多知识。但是,中心主题还是集中在 web storage (localStorage, sessionStorage) 的认识上,以及怎么使用它们。那先从 cookie 开始吧。

除了经常讨论到的 cookie、localStorage 和 sessionStorage 外,还有 IE 独有的 userData,几乎已经淘汰的 Flash(现在有 HTML5 啦),Firefox 独有的 globalStorage(Firefox13 开始不再支持),以及 Google Gears SQLite(需要安装像 Flash 那样的插件)1。现在看来,只有标准化的技术才能经住考验,得以广泛推广使用。

那今天就来好好看看历史悠久的 cookie 吧 ,学以致用!

在没有 web storage 之前,是通过 cookie 在客户端存储会话信息。它的大小限制为 4093 bytes,因此不适合大量数据的存储。这种技术是在 1993 年 Netscape 的 Lou Montulli 为了提高用户的访问速度发明的2

当用户通过 HTTP 协议访问一个服务器时,这个服务器会将一些 key/value 键值返回客户端,并给这些数据加上一些限制条件,符合条件的用户下次访问该服务器时,这些数据又被完整地返回给服务器。所以 cookie 是在客户端和服务器间来回传递的,通过 HTTP 的 Set-Cookie 响应头部设置3。例如:

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:

NameValueExpires
page_loaded25Wed, 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.frankindev.com
Cookie: page_loaded=25;
  • 简单:Cookie 是基于文本的轻量结构,用简单的键值对即可定义
  • 可配置到期规则:Cookie 可以在客户端会话结束时到期,也可以在客户端计算机上无限期存储,取决于客户端的到期规则
  • 数据持久性:虽然客户端上的 cookie 保留时间取决于客户端上的到期规则以及用户干预,但 cookie 通常是客户端上持续时间最长的数据保存形式
  • 不需要任何服务器资源:Cookie 时存储在客户端上,由客户端发送后再由服务器读取
  • 数量和长度限制:每个域的 cookie 总数是有限的。IE6 或更低版本最多有 20 个 cookie;IE7 和之后的版本最多有 50 个;Firefox 最多有 50 个;Chrome 和 Safari 没作硬性限制4。而单个 cookie 最多 4083 bytes,超出部分会被截掉。
  • 安全性:Cookie 一直在潜在隐私和安全影响方面有一个坏名声。他们很容易受到安全问题攻击影响,例如关键攻击载体的 CSRF (Cross Site Request Forgery),XSS (Cross Site Scripting Attacks) 以及 Session Hijacking 。Cookie 把所有要保存的数据通过 HTTP 协议的头部在客户端和服务器端来回传递,所有的数据都存储在客户端里,所以这些 cookie 数据可以被访问到,如果 cookie 被人拦截了,那人就可以取得所有的信息。即使加密也与事无补,因为拦截者并不需要知道 cookie 的意义,他只要原样转发 cookie 就可以达到目的了。
  • 性能问题:由于每次请求都会携带 cookie 信息,所以在 cookie 中大量存储信息会影响特定域的请求性能。

在 JS 中,可以通过 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 还有一些属性可以设置:

  1. expires 属性:该属性指定了 cookie 的生存期,默认情况下 cookie 是暂时存储的,只在客户端会话期间存在,用户退出后这些值就丢失了。如果想让 cookie 存在一段时间,就要用 expires 属性设置一个未来过期的时间。
  2. path 属性:它指定与 cookie 关联在一起的网页。默认情况下,cookie 会与创建它的网页、该网页处于同一目录下的网页以及与其子目录下的网页关联。
  3. domain 属性:domain 属性可使多个 web 服务器共享 cookie,不能将一个 cookie 的域设置成服务器所在域之外的域。
  4. 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 的话题。

参考:

avatar

Frank Lin

Code learning...