文章目录
区别
特性 | cookie | localStorage | sessionStorage |
---|---|---|---|
生命周期 | 一般由服务器生成,可设置失效时间。如果在浏览器端生成Cookie,默认是关闭浏览器后失效 | 除非被清除,否则永久保存 | 仅在当前会话下有效,关闭页面或浏览器后被清除 |
数据大小 | 4k | 5M | 5M |
与服务器端通信 | 每次都会携带在HTTP头中,如果使用cookie保存过多数据会带来性能问题 | 仅在客户端(即浏览器)中保存,不参与和服务器的通信 | 仅在客户端(即浏览器)中保存,不参与和服务器的通信 |
使用方法:(sessionStorage和localStorage类似)
// 保存数据到 sessionStorage
sessionStorage.setItem('key', 'value');
// 从 sessionStorage 获取数据
let data = sessionStorage.getItem('key');
// 从 sessionStorage 删除保存的数据
sessionStorage.removeItem('key');
// 从 sessionStorage 删除所有保存的数据
sessionStorage.clear();
localStorage如何设置过期时间
- 【重写set方法】存储时同时记录时间戳:将需要存储的对象和当前时间戳一起存储
const data = {
key: 'value',
expireAt: Date.now() + 24 * 60 * 60 * 1000 // 设置过期时间为 24 小时后
}
localStorage.setItem('data', JSON.stringify(data));
- 【重写get方法】获取数据时判断时间戳是否过期:在获取数据时,先将存储的对象解析出来,然后判断当前时间是否大于等于过期时间戳,如果是,则认为数据已过期,删除数据即可。
const storedData = localStorage.getItem('data');
if (storedData) {
const data = JSON.parse(storedData);
if (Date.now() >= data.expireAt) {
localStorage.removeItem('data');
} else {
// 数据未过期,可以使用
}
}
数据共享问题
-
cookie:在同一域名下的不同子域名之间共享,例如 www.judith.com 和 console.judith.com 之间共享cookie。通过domain和path共同决定
- 在创建cookie时,可以设置cookie的域名属性。如果设置为主域名,那么不同子域名之间就可以共享cookie。例如,如果设置域名为 judith.com ,那么www.judith.com和console.judith.com之间就可以共享cookie。
Set-Cookie: key=value; domain=.judith.com;
-
sessionStorage:在同域在不同的页签里面有时候可以共享,但是有时候不能共享
- 共享: 假如我有一个index.html页面,目前在这个页面中,有一个a链接,我们用blank新开一个页面,我链接到index.html,这个时候的sessionStorage是共享的
- 不共享:我新开一个tab标签,手动输入地址,这个时候sessionStorage不共享
-
localStorage:同一个域名下多个页面之间共享 LocalStorage 数据
根据以上知识点,回答这个问题
三个页面地址为www.baidu.com
| a.www.baidu.com
| b.www.qq.com
, cookie,sessionStorage和localstorage是否能在这些页面共享呢?
首先明白浏览器的同源策略:协议、域名、端口号完全相同
以上三个网站不符合同源策略,所以cookie,sessionStorage和localstorage都无法共享
www.baidu.com
| a.www.baidu.com
两个网站的cookie domain为.baidu.com可以实现共享
Cookie和Session基本概念
-
Cookie是客户端保存用户信息的一种机制,将服务器发送到浏览器的数据保存在本地,下次向同一服务器再发起请求时被携带发送。对于Cookie,可以设置过期时间。
出现背景:
HTTP协议是无状态的,一次请求完成,不会持久化请求与相应的信息。那么,在购物车、用户登录状态、页面个性化设置等场景下,就无法识别特定用户的信息。
常见实用场景:- 会话状态管理(如用户登录状态、购物车、游戏分数或其它需要记录的信息)
- 个性化设置(如用户自定义设置、主题等)
- 浏览器行为跟踪(如跟踪分析用户行为等)
-
Session:代表服务器和客户端一次会话的过程。是一种在服务器端保存数据的机制,用来跟踪用户状态的数据结构,可以保存在文件、数据库或者集群中。
-
Cookie+Session
- SessionID 是连接 Cookie 和 Session 的一道桥梁,大部分系统也是根据此原理来验证用户登录状态
- 目前大多数的应用都是用Cookie实现Session跟踪的。第一次创建Session时,服务端会通过在HTTP协议中返回给客户端,在Cookie中记录SessionID,后续请求时传递SessionID给服务,以便后续每次请求时都可分辨你是谁。
Cookie和Session区别
- 作用范围不同,Cookie 保存在客户端(浏览器),Session 保存在服务器端。
- 存取方式的不同,Cookie只能保存 ASCII,Session可以存任意数据类型,比如UserId等。
- 有效期不同,Cookie可设置为长时间保持,比如默认登录功能功能,Session一般有效时间较短,客户端关闭或者Session超时都会失效。
- 隐私策略不同,Cookie存储在客户端,信息容易被窃取;Session存储在服务端,相对安全一些。
- 存储大小不同, 单个Cookie 保存的数据不能超过 4K,Session可存储数据远高于Cookie。
禁用Cookie会怎样?
如果客户在浏览器禁用了Cookie,该怎么办呢?
-
方案一:拼接SessionId参数。在GET或POST请求中拼接SessionID,GET请求通常通过URL后面拼接参数来实现,POST请求可以放在Body中。无论哪种形式都需要与服务器获取保持一致。
这种方案比较常见,比如老外的网站,经常会提示是否开启Cookie。如果未点同意或授权,会发现浏览器的URL路径中往往有"?sessionId=123abc"这样的参数。 -
方案二:基于Token(令牌)。在APP应用中经常会用到Token来与服务器进行交互。Token本质上就是一个唯一的字符串,登录成功后由服务器返回,标识客户的临时授权,客户端对其进行存储,在后续请求时,通常会将其放在HTTP的Header中传递给服务器,用于服务器验证请求用户的身份。
分布式系统中Session如何处理?
在分布式系统中,往往会有多台服务器来处理同一业务。如果用户在A服务器登录,Session位于A服务器,那么当下次请求被分配到B服务器,将会出现登录失效的问题。
针对类似的场景,有三种解决方案:
-
方案一:请求精确定位。也就是通过负载均衡器让来自同一IP的用户请求始终分配到同一服务上。比如,Nginx的ip_hash策略,就可以做到。
-
方案二:Session复制共享。该方案的目标就是确保所有的服务器的Session是一致的。像Tomcat等多数主流web服务器都采用了Session复制实现Session的共享.
-
方案三:基于共享缓存。该方案是通过将Session放在一个公共地方,各个服务器使用时去取即可。比如,存放在Redis、Memcached等缓存中间件中。
在Spring Boot项目中,如果集成了Redis,Session共享可以非常方便的实现。