# 本地存储

前端常用的几种预设: cookie、sessionStorage、localStorage

cookie是什么?cookie是一个数据,用来记录一些用户相关的信息。因为服务端无法记录用户信息,所以通过客户端来记录用户信息,然后再次请求时把这个信息传给服务端,所以cookie就是为了解决 "如何记录客户端的用户信息"。

cookie的工作流程

cookie就像token的工作原理一一样。

  • 用户第一次向服务端发送请求时,服务端响应请求后,会创建一个"key-value"值(比如id)放入到响应中的Set-Cookie返回。
  • 当浏览器接收到服务端响应中返回的cookie时,浏览器会自动设置一个Cookie来存储到本地。当然也可以手动设置cookie。
  • 当用户再次向服务端发送请求时,浏览器会先检查本地有无Cookie,有的话会把相关的Cookie "key-value"对数据跟请求一起发送到服务器。
  • 服务端接收到请求,发现有Cookie,就用它来辨别身份,当然也可以继续修改。

总的来说,Cookie是保存在本地的一个字符串数据,浏览器每次访问服务器就会把对应页面的Cookie发送给服务器,这样服务器就能知道你是谁。

cookie的特点

  • 有大小限制(4KB左右)。
  • 每个网页中存储cookie的个数(最多50)和每个网站中存储cookie的个数都有限制(200)。
  • 默认情况下,cookie的有效期间是当前会话(需要把整个浏览器都关闭会话就结束)
  • 不可以跨浏览器(在IE中保存的cookie, 不可以在火狐中使用)
  • 不可以跨域(只在当前网站下使用)
  • 以name=value的方式储存(名/值对),并且是明文的(所以安全性成问题,除非用HTTPS)。
  • Cookie会被附加在每个HTTP请求中,所以无形中增加了流量。

手动设置cookie

设置Cookie:

document.cookie = 'username="xxxx"';

设置过期时间:

在值的后面添加一个expires字段,并且放一个GMT时间的值(js中放一个date对象就是GMT)。

var date = new Date();
date.setDate( date.getDate() + 7 );   // 7天过期
document.cookie = 'username="xxx"; expires=' + date + ';';

在设置Cookie的时候一次性只能设置一个Cookie,不能批量设置,如:document.cookie = 'username="xxx"&age=18';这样设置的话,Name字段仍是username,而Value字段则会变成xxx"&age=18

删除Cookie:

没有提供方法删除Cookie,但是Cookie过期就会被删除,所以只要设置一个过去的时间Cookie就自动会被删除。

var date = new Date();
date.setDate( date.getDate() - 1 );   // 给一个过去的时间
document.cookie = 'username="xxx"; expires=' + date + ';';

Cookie有4个属性:

  • expires: 生存周期
  • path: 一个路径
  • domain: 子域
  • secure: 安全性

完整代码:

// cookie都是以键值对的格式存储的,即key=value的格式。各个cookie之间一般是以“;”分隔。
// 以name为例,将此字段种到cookie中,常见操作如下:

//设置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;  
}  

//获取cookie  
function getCookie(cname) {
  var name = cname + "=";  
  var ca = document.cookie.split(';');  
  for(var i=0; i<ca.length; i++) {  
    var c = ca[i];  
    while (c.charAt(0)==' ') c = c.substring(1);  
    if (c.indexOf(name) != -1) return c.substring(name.length, c.length);  
  }  
  return "";  
}

//清除cookie    
function clearCookie(name) {    
  setCookie(name, "", -1);    
} 

# session

session机制是一种服务器端的机制,服务器使用一种类似于散列表的结构(也可能就是使用散列表)来保存信息。当程序需要为某个客户端的请求创建一个session时,服务器首先检查这个客户端的请求里是否已包含了一个session标识(称为session id),如果已包含则说明以前已经为此客户端创建过session,服务器就按照session id把这个session检索出来使用(检索不到,会新建一个),如果客户端请求不包含session id,则为此客户端创建一个session并且生成一个与此session相关联的session id,session id的值应该是一个既不会重复,又不容易被找到规律以仿造的字符串,这个session id将被在本次响应中返回给客户端保存。

保存这个session id的方式可以采用cookie,这样在交互过程中浏览器可以自动的按照规则把这个标识发送给服务器。一般这个cookie的名字都是类似于SEEESIONID。但cookie可以被人为的禁止,则必须有其他机制以便在cookie被禁止时仍然能够把session id传递回服务器。经常被使用的一种技术叫做URL重写,就是把session id直接附加在URL路径的后面。比如:http://damonare.cn?sessionid=123456还有一种技术叫做表单隐藏字段。就是服务器会自动修改表单,添加一个隐藏字段,以便在表单提交时能够把session id传递回服务器

session流程:

  • 浏览器第一次请求网站, 服务端生成 Session ID。
  • 把生成的 Session ID 保存到服务端存储中。
  • 把生成的 Session ID 返回给浏览器,通过 set-cookie。
  • 浏览器收到 Session ID, 在下一次发送请求时就会带上这个 Session ID。
  • 服务端收到浏览器发来的 Session ID,从 Session 存储中找到用户状态数据,会话建立。
  • 此后的请求都会交换这个 Session ID,进行有状态的会话。

# Cookie和Session 的区别

  • 1、cookie数据存放在客户的浏览器上,session数据放在服务器上。
  • 2、cookie不是很安全,别人可以分析存放在本地的cookie并进行cookie欺骗,考虑到安全应当使用session。
  • 3、session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能考虑到减轻服务器性能方面,应当使用cookie。
  • 4、单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie。
  • 5、所以建议:
    • 将登陆信息等重要信息存放为SESSION
    • 其他信息如果需要保留,可以放在cookie中

# web storage

web storage 分为 localStorage和 sessionStorage两种,都是浏览器本地存储。不像cookie和session是浏览器和服务端来回传递,只作用于本地。

localStorage:以键值对(Key-Value)的方式存储,永久存储,永不失效,除非手动删除。localStorage在隐私模式下不可被访问,数据多的话会很卡。

sessionStorage: 和localStorage类似,只是sessionStorage 在关闭页面后即被清空,而 localStorage 则会一直保存。很多时候数据只需要在用户浏览一组页面期间使用,关闭窗口后数据就可以丢弃了,这种情况使用sessionStorage就比较方便。

使用:

// 设置storage 以键值对方式存储,都是字符串
window.sessionStorage.setItem('key', 'value');
window.localStorage.setItem('key', 'value');

// 下面三种写法等价
window.localStorage.foo = '123';
window.localStorage['foo'] = '123';
window.localStorage.setItem('foo', '123');

// 读取
window.sessionStorage.getItem('key');
window.localStorage.getItem('key');

// 清除某个
sessionStorage.removeItem('key');
localStorage.removeItem('key');

// 清除所有
window.sessionStorage.clear();
window.localStorage.clear();

// 获取个数
window.localStorage.length
window.sessionStorage.length

// 获取键名
window.localStorage.key(0) // "key"
window.sessionStorage.key(0) // "key"

// 遍历所有键
for (var i = 0; i < window.localStorage.length; i++) {
  console.log(localStorage.key(i));
}

// 监听storage事件

window.addEventListener('storage', onStorageChange);

function onStorageChange(e) {
  console.log(e.key);
}

# 其他存储方式

WebSQL、IndexDB、cacheStorage

浏览器端数据库indexedDB

Websocket协议

参考链接:

Cookie工作原理 (opens new window)

会话机制——cookie和session (opens new window)

Javascript 本地存储小结 (opens new window)