本地存储的几种对比
本地存储的几种简单对比
1、cookie:4K,可以手动设置失效期 2、localStorage:5M,除非手动清除,否则一直存在 3、sessionStorage:5M,不可以跨标签访问,页面关闭就清理 4、indexedDB:浏览器端数据库,无限容量,除非手动清除,否则一直存在 5、service worker 实现离线缓存
SW 除了 work 线程的限制外,由于可拦截页面请求,为了保证页面安全,浏览器端对 sw 的使用限制也不少。
1)无法直接操作 DOM 对象,也无法访问 window、document、parent 对象。可以访问 location、navigator;
2)可代理的页面作用域限制。默认是 sw.js 所在文件目录及子目录的请求可代理,可在注册时手动设置作用域范围;
3)必须在 https 中使用,允许在开发调试的 localhost 使用。
浏览器的本地存储技术主要用于在客户端保存数据,以减少对服务器的请求,提升用户体验。常见的浏览器本地存储技术包括 Cookie、LocalStorage、SessionStorage 和 IndexedDB。以下是它们的详细对比:
1. Cookie
1.1 特点
存储大小:最多 4KB。
生命周期:可以设置过期时间,默认在浏览器关闭时失效。
作用域:可以设置作用域(Domain 和 Path)。
通信方式:每次 HTTP 请求都会携带 Cookie,增加请求头的大小。
1.2 适用场景
会话管理:如用户登录状态。
个性化设置:如用户偏好设置。
跟踪用户行为:如广告跟踪。
1.3 优缺点
优点:
兼容性好,所有浏览器都支持。
可以设置过期时间。
缺点:
存储空间小。
每次请求都会携带,增加网络开销。
2. LocalStorage
2.1 特点
存储大小:通常为 5MB(不同浏览器可能不同)。
生命周期:永久存储,除非手动清除。
作用域:同一域名下的所有页面共享。
通信方式:仅在客户端存储,不会随请求发送。
2.2 适用场景
持久化数据:如用户偏好设置、缓存数据。
离线数据存储:如保存用户未提交的表单数据。
2.3 优缺点
优点:
存储空间较大。
数据永久存储,除非手动清除。
缺点:
仅支持字符串类型的数据。
不适合存储敏感数据。
3. SessionStorage
3.1 特点
存储大小:通常为 5MB(不同浏览器可能不同)。
生命周期:仅在当前会话有效,关闭浏览器或标签页后数据被清除。
作用域:仅在当前标签页有效,不同标签页不共享。
通信方式:仅在客户端存储,不会随请求发送。
3.2 适用场景
临时数据存储:如表单数据、页面状态。
单页应用(SPA)的状态管理。
3.3 优缺点
优点:
存储空间较大。
数据仅在当前会话有效,安全性较高。
缺点:
数据生命周期短,关闭浏览器后失效。
仅支持字符串类型的数据。
4. IndexedDB
4.1 特点
存储大小:通常为 50MB 以上(不同浏览器可能不同)。
生命周期:永久存储,除非手动清除。
作用域:同一域名下的所有页面共享。
通信方式:仅在客户端存储,不会随请求发送。
数据类型:支持存储复杂数据类型(如对象、数组)。
4.2 适用场景
大量结构化数据存储:如离线应用、缓存大量数据。
复杂查询需求:如需要索引和查询的数据。
4.3 优缺点
优点:
存储空间大。
支持复杂数据类型和索引。
适合存储大量数据。
缺点:
API 较复杂,使用难度较高。
兼容性较差(旧版浏览器可能不支持)。
5. 对比总结
特性
Cookie
LocalStorage
SessionStorage
IndexedDB
存储大小
4KB
5MB
5MB
50MB 以上
生命周期
可设置过期时间
永久存储
会话级别
永久存储
作用域
可设置 Domain 和 Path
同一域名下共享
当前标签页有效
同一域名下共享
通信方式
每次请求携带
不随请求发送
不随请求发送
不随请求发送
数据类型
字符串
字符串
字符串
复杂数据类型(对象、数组等)
适用场景
会话管理、用户跟踪
持久化数据、缓存
临时数据存储
大量结构化数据存储
兼容性
所有浏览器
所有现代浏览器
所有现代浏览器
大部分现代浏览器
6. 如何选择合适的存储技术?
小量数据且需要随请求发送:选择 Cookie。
持久化存储且数据量较大:选择 LocalStorage。
临时存储且数据量较大:选择 SessionStorage。
大量结构化数据存储:选择 IndexedDB。
7. 最佳实践
敏感数据:避免在客户端存储敏感数据(如密码、令牌),即使存储也要加密。
数据清理:定期清理无用数据,避免占用过多存储空间。
兼容性处理:在使用 IndexedDB 等新技术时,注意兼容性问题,提供降级方案。
通过合理选择和使用浏览器本地存储技术,可以显著提升 Web 应用的性能和用户体验。
session 和 cookie
cookie
Cookie 是由客户端保存的小型文本文件,其内容为一系列的键值对.Cookie 是由 HTTP 服务器设置的,保存在浏览器中.
浏览器向某个 URL 发起 HTTP 请求(可以是任何请求,比如 GET 一个页面、POST 一个登录表单等)
对应的服务器收到该 HTTP 请求,并计算应当返回给浏览器的 HTTP 响应。
在响应头加入 Set-Cookie 字段,它的值是要设置的 Cookie。
浏览器收到来自服务器的 HTTP 响应。
浏览器在响应头中发现 Set-Cookie 字段,就会将该字段的值保存在内存或者硬盘中。
浏览器下次给该服务器发送 HTTP 请求时, 会将服务器设置的 Cookie 附加在 HTTP 请求的头字段 Cookie 中。浏览器可以存储多个域名下的 Cookie,但只发送当前请求的域名曾经指定的 Cookie, 这个域名也可以在 Set-Cookie 字段中指定)
服务器收到这个 HTTP 请求,发现请求头中有 Cookie 字段, 便知道之前就和这个用户打过交道了。
过期的 Cookie 会被浏览器删除。
服务器通过 Set-Cookie 响应头字段来指示浏览器保存 Cookie, 浏览器通过 Cookie 请求头字段来告诉服务器之前的状态。 Cookie 中包含若干个键值对,每个键值对可以设置过期时间。
cookie 的属性
Max-Age
定义: 指定 Cookie 的有效期,以秒为单位
行为:
如果 Max-Age 为正数,浏览器会将其持久化,即写入到对应的 Cookie 文件中。
如果 Max-Age 为零或负数,浏览器会立即删除该 Cookie。
优先级: 如果同时设置了 Expires 和 Max-Age,Max-Age 的优先级更高。
Expires
定义: 指定 Cookie 的过期时间,格式为 GMT 时间。
行为:
如果未设置 Expires,则默认为会话 Cookie,即浏览器关闭时删除。
如果设置了 Expires,则为持久性 Cookie,直到指定的时间点过期。
注意: Expires 的值与客户端的时区相关
Domain
定义: 指定 Cookie 可以发送到的主机名。
行为:
如果未指定,默认为当前文档访问地址中的主机部分(不包含子域名)。
例如,设置 Domain=.example.com,则 a.example.com 和 b.example.com 都可以访问该 Cookie。
限制: 不能跨域设置 Cookie,例如,无法将 Domain 设置为 baidu.com。
Secure
定义: 指示浏览器仅通过 HTTPS 协议发送该 Cookie。
行为:
只有在使用 HTTPS 协议时,浏览器才会发送该 Cookie。
有助于保护 Cookie 在传输过程中的安全性。
HttpOnly
定义: 指示浏览器禁止客户端脚本(如 JavaScript)访问该 Cookie。
行为:
防止通过 document.cookie 等方式访问 Cookie。
有助于防止跨站脚本攻击(XSS)
SameSite
定义: 指示浏览器在跨站请求时是否发送该 Cookie。
取值:
Strict:仅在同一站点的请求中发送 Cookie。
Lax:在部分跨站请求中发送 Cookie,例如,GET 请求导航到目标站点时。
None:在所有跨站请求中发送 Cookie,但需要同时设置 Secure 属性。
注意: Chrome 80 版本后,默认值为 Lax。
cookie 防篡改机制
服务器可以为每个 cookie 项生成签名, 由于用户篡改 cookie 后无法生成对应的签名, 服务器便可以得知用户对 cookie 进行了篡改
在服务器中配置一个不为人知的字符串(secret), 比如: x&sjh23;
在服务器需要设置 cookie 时,比如(authed=false), 不仅设置 authed 的值为 false, 在值的后面进一步设置一个签名, 最终设置的 cookie 是 authed=false|6hTiBl7lVpd1P;
签名 6hTiBl7lVpd1P 是这样生成的:Hash('x&sjh23'+'false')。 要设置的值与 Secret 相加再取哈希。
用户收到 HTTP 响应并发现头字段 Set-Cookie: authed=false|6hTiBl7lVpd1P。
用户在发送 HTTP 请求时,篡改了 authed 值,设置头字段 Cookie: authed=true|???。 因为用户不知道 Secret,无法生成签名,只能随便填一个。
服务器收到 HTTP 请求,发现 Cookie: authed=true|???。服务器开始进行校验: Hash('true'+'x&sjh23'),便会发现用户提供的签名不正确。
因为 Cookie 是明文传输的, 只要服务器设置过一次 authed=true|xxxx 我不就知道 true 的签名是 xxxx 了么, 以后就可以用这个签名来欺骗服务器了。因此 Cookie 中最好不要放敏感数据。 一般来讲 Cookie 中只会放一个 Session Id,而 Session 存储在服务器端。
cookie 跨域
通过这是 nginx 代理服务器, 将两个服务器域名统一到一个反向代理服务器
CORS 协议 前端: 客户端使用 XMHLHttpRequest 发起 Ajax 请求,当前绝大部分浏览器已经支持 CORS 方式,且主流浏览器均提供了对跨域资源共享的支持。
让后台修改,支持某些前端域名的跨域。php 代码如下:
header('Access-Control-Allow-Origin:'); //支持所有前端域名,但是有个问题,就是不支持 Cookie 的跨域
也可以动态设置跨域。header('Access-Control-Allow-Origin:'.$_SERVER['HTTP_ORIGIN']);//如果请求涉及到跨域,那么 origin 会自动带上前端域名信息。这样做还有一个好处,可以支持 cookie 跨域
对于 nodejs 做如下配置可允许资源的跨域访问:
Access-Control-Allow-Origin:* 表示允许任何域发起请求,如果只允许特定的域访问,则设置 Access-Control-Allow-Origin:xxx 为具体域名即可。
怎么让 Ajax 请求都带上 Cookie & cookie 跨域
客户端需要设置 Ajax 请求属性 withCredentials=true
对于 XMLHttpRequest 的 Ajax 请求
服务端进行设置
设置 1. 解决顶级域名与二级域名之间的 cookie 跨域问题
通过设置 domain
顶级域名服务器与二级域名服务器之间哪个设置都能生效
设置完毕后写回到客户端,用另一个服务器即可访问此 Cookie
二级域名能读取设置了 domain 为顶级域名或者自身的 cookie,不能读取其他二级域名 domain 的 cookie。例如:要想 cookie 在多个二级域名中共享,需要设置 domain 为顶级域名,这样就可以在所有二级域名里面或者到这个 cookie 的值了。
顶级域名只能获取到 domain 设置为顶级域名的 cookie,domain 设置为其他子级域名的无法获取。 读取 COOKIE
修改 cookie
顶级域名 顶级域名的 cookie 在顶级域名或者非顶级域名[需要设置 domain 为顶级域名才可以] 都可以修改.
#为所有二级域名设置一个 cookie setcookie("name", "yangbai", time() + 1000, "/", "yangbai.com");
二级域名
修改二级域名自身生成的 cookie 不需要设置 domain, 直接设置即可
删除 cookie
#删除 yangbai.com 下面的 cookie 值 setcookie("name", null, time() - 1000, "/", "yangbai.com");
#删除 game.yangbai.com 下面自身的 cookie 值 setcookie("game", null, time() - 1000);
jsonp
将 get 请求伪装成一个 script 文件的加载。就可以绕过跨域的问题为了。
session
Session 是存储在服务器端的,避免了在客户端 Cookie 中存储敏感数据。 Session 可以存储在 HTTP 服务器的内存中,也可以存在内存数据库(如 redis)中, 对于重量级的应用甚至可以存储在数据库中。
用户提交包含用户名和密码的表单,发送 http 请求.
服务器验证用户发来的用户密码.
如果正确则把当前用户名存储到 redis 中,并生成它在 redis 中的 id.这个 ID 称为 Session ID,通过 Session ID 可以从 Redis 中取出对应的用户对象, 敏感数据(比如 authed=true)都存储在这个用户对象中。
设置 Cookie 为 sessionId=xxxxxx|checksum 并发送 HTTP 响应, 仍然为每一项 Cookie 都设置签名。
用户收到 HTTP 响应后,便看不到任何敏感数据了。在此后的请求中发送该 Cookie 给服务器。
服务器收到此后的 HTTP 请求后,发现 Cookie 中有 SessionID,进行防篡改验证。
如果通过了验证,根据该 ID 从 Redis 中取出对应的用户对象, 查看该对象的状态并继续执行业务逻辑。
Web 应用框架都会实现上述过程,在 Web 应用中可以直接获得当前用户。 相当于在 HTTP 协议之上,通过 Cookie 实现了持久的会话。这个会话便称为 Session。
localStorage 和 sessionStorage 区别
特性 SessionStorage LocalStorage 跨标签页 不能跨标签页共享 | 可以跨标签页共享 作用域 当前标签页 | 同一域名下的所有标签页 生命周期 会话级别,关闭标签页后失效 | 永久存储,除非手动清除 适用场景 临时数据存储 | 持久化数据存储 如果需要 跨标签页共享数据,使用 LocalStorage。 | 如果数据仅需在 当前标签页 使用,使用 SessionStorage。
如果需要更复杂的跨标签页通信,可以使用 LocalStorage 事件
最后更新于
这有帮助吗?