存储界:cookie、localstorage、sessionstorage
绑定在特定域名下,无法跨越浏览器对cookie数量的限制规定不同(例如FF规定每个域名最多50个,二Safari和chrome没有数量限制)所有cookie的累加长度限制为4KB,超长会被忽略(除了cookie本身的内容,还有部分可选属性可以被写入,必须都以分号开头)本地存储,存储的数据没有过期时间注:各浏览器支持的localStorage容量上限不同会话存储,存储的数据会在浏览器会话结束时被清除
文章目录
cookie、本地存储、会话存储三者均可以存储数据,存储的时效性有区别
一、cookie
1、是什么
所谓“cookie
”数据是指某些网站为了辨别用户身份,储存在用户本地终端上的数据(通常经过加密),由用户客户端计算机暂时或永久保存的信息。
2、cookie的构成
cookie
作为用户登录时的一种状态信息,Cookie
是保存在客户端的纯文本文件。比如txt文件。所谓的客户端就是我们自己的本地电脑。当我们使用自己的电脑通过浏览器进行访问网页的时候,服务器就会生成一个证书并返回给我的浏览器并写入我们的本地电脑。这个证书就是cookie。一般来说cookie都是服务器端写入客户端的纯文本文件。
原理:web服务器通过在http响应消息头增加Set-Cookie响应头字段将Cookie信息发送给浏览器,浏览器则通过在http请求消息中增加Cookie请求头字段将Cookie回传给web服务器。
名称 | Value |
---|---|
名称 name | 一个唯一确定cookie的名称 |
值value | 存储在cookie中的字符串 |
域domain:cookie | cookie对于哪个域是有效的 |
路径 path | 指定域中的指定路径 |
失效时间 expires | cookie何时应该被删除的时间戳 |
max-age | 与expires作用相同,用来告诉浏览器此cookie多久过期(单位是秒),而不是一个固定的时间点。正常情况下,max-age的优先级高于expires。 |
HttpOnly | 告知浏览器不允许通过脚本document.cookie去更改这个值,同样这个值在document.cookie中也不可见。但在http请求仍然会携带这个cookie。注意这个值虽然在脚本中不可获取,但仍然在浏览器安装目录中以文件形式存在。这项设置通常在服务器端设置。 |
安全标志secure | 指定后,cookie只有在使用SSL连接时才发送到服务器(设置secure标准) |
3、cookie 的工作原理
话不多说。先上一张图帮助大家理解cookie 。以登录gitHub仓库为例
原理如下:
问:当我们把浏览器种的cookie信息复制到另一个浏览器中保存进行访问,是不是也可以不用登录直接访问,那这个时候就需要用到cookie劫持
4、cookie的限制
绑定在特定域名下,无法跨越
浏览器对cookie
数量的限制规定不同(例如FF规定每个域名最多50个,二Safari和chrome没有数量限制)
所有cookie的累加长度限制为4KB,超长会被忽略
名称 | Value |
---|---|
JS中的cookie | document.cookie |
获取 | 返回当前页面可用的所有cookie的字符串,由分号和空格隔开的一系列名值对(name1 = value1; name2 = value2;) |
添加 | cookie的值必须写成key = value的形式,且等号两边不能有空格写入时必须对分号,逗号和空格进行转义(encodeURLComponent()方法)一次只能写入一个cookie,并且写入不是覆盖,而是添加 |
- 会话cookie是指在不设定它的生命周期 expires 时的状态,前面说了,浏览器的开启到关闭就是一次会话,当关闭浏览器时,会话cookie就会跟随浏览器而销毁。当关闭一个页面时,不影响会话cookie的销毁。
5、cookie的属性
(除了cookie本身的内容,还有部分可选属性可以被写入,必须都以分号开头)
名称 | Value |
---|---|
value | 必需项,用于指定cookie的值 |
expires | 指定cookie过期时间,也指cookie的周期 |
domain | 指定cookie所在域名(只有访问的域名匹配domain属性,cookie才会发送到服务器) |
path属性 | 指定路径,必须是绝对路径 |
secure | 指定cookie只能在加密协议https下发送到服务器 |
httpOnly | 设置该cookie不能被JS读取 |
二、localStorage(本地存储)
1. 是什么
本地存储,在HTML5中,加入了一个localStorage特性,这个特性主要是用来作为本地存储来使用的,解决了cookie存储空间不足的问题(cookie中每条cookie的存储空间为4k),localStorage中一般浏览器支持的是20M大小,这个在不同的浏览器中localStorage会有所不同。它只能存储
字符串格式
的数据,所以最好在每次存储时把数据转换成json
格式,取出的时候再转换回来。数据没有过期时间。
名称 | Value |
---|---|
语法: | myStorage = localStorage;返回一个Storage对象 |
添加: | localStorage.setltem(‘key’,‘value’); |
获取: | localStorage.getItem(‘key’); 如果key不存在则返回null |
移除: | localStorage.removeItem(‘key’); 删除名称为“key”的信息,这个key所对应的value也会全部被删除 |
清空: | localStorage.clear(); 不接收参数,清空存储对象里的所有数据 |
2. 特点
-
生命周期永久有效,除非手动删除,否则关闭页面也会存在
-
可以多窗口(页面)共享(同一浏览器可以共享)
-
以键值对的形式存储使用
-
各浏览器支持的localStorage容量上限不同;
-
localStorage.getItem(‘key’); 如果key不存在则返回null,而不是 undefined
例:标准的json对象{“name”:“john”}
JSON.stringify();
// 将json格式的数据(JavaScript 对象)转换成JSON格式的字符串
例:var data = {name:"john"}; data = JSON.stringify(data); localStorage.setItem("data1",data);
JSON.parse()
; //将JSON格式的字符串转换成JSON对象进行处理
3. 问:会自动删掉吗?
localStorage
是 Web Storage API
的一部分,它提供了一种存储键值对的机制。localStorage
的数据是持久存储在用户的硬盘上的,而不是内存。这意味着即使用户关闭浏览器或电脑,localStorage
中的数据也不会丢失,除非主动清除浏览器缓存或者使用代码删除。
当你通过 JavaScript
访问 localStorage
时,浏览器会从硬盘中读取数据或向硬盘写入数据。然而,在读写操作期间,数据可能会被暂时存放在内存中,以提高处理速度。但主要的特点是它的持久性,以及它不依赖于会话的持续性。
4. 问:读取操作是同步还是异步?
- 在 Web 浏览器环境中,
localStorage
的API
是设计为同步的,即使底层的硬盘读写操作有着IO的特性。 js
代码在访问localStorage
时,浏览器提供的API接口通常会处于js
执行线程上下文中直接调用。这意味着尽管硬盘是IO设备,当一个js
执行流程访问localStorage
时,它将同步地等待数据读取或写入完成,该过程中js执行线程会阻塞。- 这种同步API设计意味着开发者在操作
localStorage
时不需要考虑回调函数或者Promise
等异步处理模式,可以按照同步代码的方式来编写。不过,这也意味着如果涉及较多数据的读写操作时,可能对性能产生负面影响,特别是在主线程上,因为它会阻塞UI的更新和其他js
的执行。
5. 执行的完整操作流程
localStorage
实现同步存储的方式就是阻塞 JavaScript
的执行,直到数据的读取或者写入操作完成。这种同步操作的实现可以简单概述如下:
- js线程调用: 当
JavaScript
代码执行一个localStorage
的操作,比如localStorage.getItem('key')
或localStorage.setItem('key', 'value')
,这个调用发生在js
的单个线程上。 - 浏览器引擎处理: 浏览器的
js
引擎接收到调用请求后,会向浏览器的存储子系统发出同步IO请求。此时js
引擎等待IO操作的完成。 - 文件系统的同步IO: 浏览器存储子系统对硬盘执行实际的存储或检索操作。尽管操作系统层面可能对文件访问进行缓存或优化,但从浏览器的角度看,它会进行一个同步的文件系统操作,直到这个操作返回结果。
- 操作完成返回: 一旦IO操作完成,数据要么被写入硬盘,要么被从硬盘读取出来,浏览器存储子系统会将结果返回给
js
引擎。 JavaScript
线程继续执行:js
引擎在接收到操作完成的信号后,才会继续执行下一条js
代码。
在同步的 localStorage
操作期间,由于 js
的单线程性质,整个线程会阻塞,即不会执行其他任何js
代码,也不会进行任何渲染操作,直到 localStorage
调用返回。
6. localStorage限制容量都是因为同步会阻塞的原因吗?
- 资源公平分享:同一用户可能会访问大量不同的网站,如果没有限制,随着时间的积累,每个网站可能会消耗大量的本地存储资源。这样会导致本地存储空间被少数几个站点占用,影响到用户访问其他网页的体验。限制大小可以确保所有网站都有公平的存储机会。
- 防止滥用:如果没有存储限制,网站可能会滥用
localStorage
,存储大量数据在用户的设备上,这可能导致设备存储空间迅速耗尽,也可能侵犯用户的隐私。 - 性能限制:如之前提到的,
localStorage
的操作是阻塞的。如果网站能够存储大量数据,就会加剧读写操作对页面性能的影响。 - 存储效率:
localStorage
存储的是字符串形式的数据,不是为存储大量或结构化数据设计的。当尝试存储过多数据时,效率会降低。 - 历史和兼容性:5MB 的限制很早就已经被大多数浏览器实现,并被作为一个非正式的标准被采纳。尽管现在有些浏览器支持更大的
localStorage
,但出于跨浏览器兼容性的考虑,开发者通常会假设这个限制。 - 浏览器政策:浏览器厂商可能会依据自己的政策来设定限制,可能是出于提供用户更一致体验的角度,或者是出于管理用户数据的方便。
三、sessionStorage(会话存储)
1、是什么
- 客户端请求服务端,服务端会为这次请求开辟一块内存空间,这个对象便是
Session
对象,存储结构为ConcurrentHashMap
。Session
弥补了 HTTP 无状态特性,服务器可以利用Session
存储客户端在同一个会话期间的一些操作记录。 - 服务器第一次接收到请求时,开辟了一块
Session
空间(创建了Session
对象),同时生成一个sessionId
,并通过响应头的Set-Cookie:JSESSIONID=XXXXXXX
命令,向客户端发送要求设置Cookie
的响应; 客户端收到响应后,在本机客户端设置了一个JSESSIONID=XXXXXXX
的Cookie
信息,该Cookie
的过期时间为浏览器会话结束;
-
接下来客户端每次向同一个网站发送请求时,请求头都会带上该
Cookie
信息(包含sessionId
), 然后,服务器通过读取请求头中的Cookie
信息,获取名称为JSESSIONID
的值,得到此次请求的sessionId
。 -
会话,代表服务器与浏览器的一次会话过程,这个过程是连续的,也可以时断时续。
-
cookie
中存放着一个sessionID
,请求时会发送这个ID,Session
依据Cookie
来识别是否是同一个用户; -
Session
是另一种记录客户状态的机制,不同的是Cookie
保存在客户端浏览器中,而Session
保存在服务器上。客户端浏览器访问服务器的时候,服务器把客户端信息以某种形式记录在服务器上。客户端浏览器再次访问时只需要从该Session
中查找该客户的状态就可以了。 -
session
因为请求(request对象)而产生;session
的创建与使用总是在服务端,浏览器从来都没有得到过session
对象; -
session
是一个容器,数据存储在用户浏览器中,可以存放会话过程中的任何对象; -
session
是一种http存储机制,目的是为武装的http提供持久机制。 -
设置、读取方便,甚至页面刷新不丢失数据
-
容量较大,
sessionStroage
约 5M,localStorage
约 20 M -
只能存储字符串,可以将对象 JSON.stringify() 编码后存储
-
生命周期为关闭浏览器窗口,并且在 同一个窗口(页面)下数据是可以共享的,数据以键值对的形式存储使用
2、使用
- 存储数据
sessionStorage.setItem(key,value)
- 获取数据
sessionStorage.getItem(key)
- 删除数据
sessionStorage.removeItem(key)
- 删除所有数据数据
sessionStorage.clear()
四、Token
- 一个Token就是一些信息的集合;
- 在Token中包含足够多的信息,以便在后续请求中减少查询数据库的几率;
- 服务端需要对cookie和HTTP Authrorization Header进行Token信息的检查;
- 基于上一点,你可以用一套token认证代码来面对浏览器类客户端和非浏览器类客户端;
- 因为token是被签名的,所以我们可以认为一个可以解码认证通过的token是由我们系统发放的,其中带的信息是合法有效的;
五、Cookie 和 Token
Cookie 和 Token 是两种不同的概念,但它们在 Web 应用程序中有一定的关系和区别:
1. Cookie:
- 定义:Cookie 是由服务器发送到用户浏览器并保存在本地的小型文本文件,用于在浏览器和服务器之间存储状态信息。
- 特点:通常用于跟踪用户的会话状态(如登录状态)、存储用户的偏好设置或者追踪用户的行为等。
- 用途:主要用于实现用户状态的保持,例如保持用户登录状态、跟踪用户活动等。
2. Token:
- 定义:Token 是一种代表用户身份和权限的令牌,通常是一个字符串,由服务器签发并发送给客户端(如浏览器),客户端在接下来的请求中使用这个令牌来进行身份验证或授权。
- 特点:一般是随机生成的唯一字符串,可以包含加密信息以确保安全性。
- 用途:主要用于在分布式系统中进行身份验证和授权,如 OAuth 授权流程中的 Access Token、JWT(JSON Web Token)等。
关系与区别:
3. 关系:
Cookie 可以用来存储 Token。例如,服务器可以将身份验证成功后生成的 Token 存储在一个 Cookie 中,浏览器在接下来的请求中会自动发送这个 Token,从而实现持久的身份验证。
4. 区别:
- 功能不同:Cookie 是一种存储状态信息的机制,而 Token 是一种安全身份验证和授权的机制。
- 存储位置:Cookie 存储在客户端浏览器中,而 Token 也可以存储在客户端,但通常是用于在不同服务或系统之间传递身份信息。
- 安全性:Token 通常比 Cookie 更安全,因为它可以包含加密签名或其他安全机制,而 Cookie 可能会受到跨站点脚本攻击(XSS)或跨站请求伪造(CSRF)等攻击的影响。
5. 总结
总结来说,Cookie 是用于存储状态信息的一种机制,而 Token 则是用于安全身份验证和授权的一种机制,它们可以结合使用,但是在不同的上下文和目的下有着不同的应用和安全考量。
六、案例:记住用户名
思路:
- 把数据存起来,用到本地存储
- 关闭页面,也可以显示用户名,所以用 localStorage
- 打开页面,先判断是否有这个用户名,如果有,就在表单里面显示用户名,并且勾选复选框
- 当复选框发生改变的时候 change 事件
<body>
<input type="text" id="username">
<input type="checkbox" id="remember">
记住用户名
<script>
var username = document.querySelector('#username');
var username = document.querySelector('#remember');
if (localStroage.getItem('username')) {
username.value = localStorage.getItem('username');
remember.checked = true;
}
remember.addEventListener('change',function(){
if (this.checked) {
localStorage.setItem('username',username.value)
}else{
localStorage.removeItem('username');
}
})
</script>
</body>
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)