前端本地存储方式
1.前端本地存储都有那些方式
- cookie
- localStorage
- sessionStorage
- indexedDB
cookie
基本的概念和被创造出的目的
cookie是服务器发送到用户浏览器并保存在本地的一小块数据。浏览器会存储 cookie 并在下次向同一服务器再发起请求时携带并发送到服务器上。是为了解决 HTTP无状态导致的问题
Cookie 曾一度用于客户端数据的存储,因当时并没有其他合适的存储办法而作为唯一的存储手段,但现在推荐使用现代存储 API(也就是我们后面即将介绍的前端本地存储)。
主要的使用场景
- 会话状态管理,如用户登录状态、购物车、游戏分数或其他需要记录的信息
- 个性化设置,如用户自定义设置、主题和其他设置
- 浏览器行为跟踪,如跟踪分析用户行为等
Cookie的创建过程
服务器收到 HTTP 请求后,服务器可以在响应标头里面添加一个或多个 Set-Cookie 选项。浏览器收到响应后通常会保存下 Cookie,并将其放在 HTTP Cookie 标头内,向同一服务器发出请求时一起发送。你可以指定一个过期日期或者时间段之后,不能发送 cookie。你也可以对指定的域和路径设置额外的限制,以限制 cookie 发送的位置。
cookie长什么样子?
//这里我们以GitHub的cookie为例
-> document.cookie//读取所有可从此位置访问的 COOKIE
<- `
_octo=GH1.1.7260188.1707192967;
color_mode=%7B%22color_mode%22%3A%22auto%22%2C%22light_theme%22%3A%7B%22name%22%3A%22light%22%2C%22color_mode%22%3A%22light%22%7D%2C%22dark_theme%22%3A%7B%22name%22%3A%22dark%22%2C%22color_mode%22%3A%22dark%22%7D%7D;
preferred_color_mode=light;
tz=Asia%2FShanghai`
//是一个基本呈现key,value值的一个字符串!cookie的一些重要属性
name (必要) 要创建或覆盖的 cookie 的名字 (string)。
value (必要) cookie 的值 (string)。
end (可选) 最大年龄的秒数 (一年为 31536e3,永不过期的 cookie 为Infinity (en-US)) ,或者过期时间的 GMTString 格式或Date 对象; 如果没有定义则会在会话结束时过期 (number – 有限的或 Infinity (en-US) – string, Date object or null)。
path (可选) 例如 '/', '/mydir'。如果没有定义,默认为当前文档位置的路径。(string or null)。路径必须为绝对路径
domain (可选) 例如 'example.com','.example.com' (包括所有子域名), 'subdomain.example.com'。如果没有定义,默认为当前文档位置的路径的域名部分 (string 或 null)。
secure (可选) cookie 只会被 https 传输 (boolean或null)。
生命周期
cookie若未设置时间end属性,那么浏览器默认会将其设置为会话Cookie,在用户关闭浏览器后会被自动删除。若设置时间则会被存储到硬盘中。
cookie和token的关系
token 是另一种流行的处理 http 无状态的方式,一般设置在请求头中。当用户登录成功时返回 token 给客户端,客户端再次请求时携带 token,服务端获取 token 后,再从 session 中获取用户信息及登录状态。 与 cookie 相比,因为 token 在代码中设置,不会在访问第三方网站时携带 cookie,可以有效避免 csrf 攻击。
带来的问题
- cookie 的大小一般被浏览器限制为 4kb
- 请求自动携带 cookie 其实会造成无效的带宽浪费, 可以通过withcredits:false取消携带(axios取消的做法)
- 安全问题(csrf 与 xss)
localStorage 和 session storage
二者都是属于Web Storage,是两种机制
这两种机制是通过 Window.sessionStorage 和 Window.localStorage 属性使用(更确切的说,在支持的浏览器中 Window 对象实现了 WindowLocalStorage 和 WindowSessionStorage 对象并挂在其 localStorage 和 sessionStorage 属性下)——调用其中任一对象会创建 Storage 对象,通过 Storage 对象,可以设置、获取和移除数据项。对于每个源 sessionStorage 和 localStorage 使用不同的 Storage 对象——独立运行和控制。
sessionStorage 为每一个给定的源(origin)维持一个独立的存储区域,该存储区域在页面会话期间可用(即只要浏览器处于打开状态,包括页面重新加载和恢复)。 仅为会话存储数据,这意味着数据将一直存储到浏览器(或选项卡)关闭。 数据永远不会被传输到服务器。 存储限额大于 cookie(最大 5MB)。
localStorage 做同样的事情,但即使浏览器关闭并重新打开也仍然存在。 存储的数据没有过期日期,只能通过 JavaScript、清除浏览器缓存或本地存储的数据来清除。 存储限额是两者之间的最大值。
二者是什么样子的?
//我们还是以GitHub为例
> window.localStorage
<.
Storage {ref-selector:Dixeran/RoadMap:branch: '{"refs":["master","dev","gh-pages"],"cacheKey":"v0:1525584698.0"}', ref-selector:dboooo/interview:branch: '{"refs":["main"],"cacheKey":"v0:1709183438.0"}', heardHelpAnnouncement: 'true', ref-selector:vuejs/vitepress:branch: '{"refs":["main","feat/hash","fix/2989","progressba…-and-anchor-check"],"cacheKey":"v0:1708338376.0"}', bundle-urls: '{"wp-runtime.js":"https://github.githubassets.com/…ules_github_quote-select-67e0dc-1aa35af077a4.js"}', …}
//因为整个storage对象很大,这里就不再仔细查看
//sessionStorage以YouTube为例,它需要的会话存储较多
> window.sessionStorage
.> Storage {yt-remote-session-app: '{"data":"youtube-desktop","creation":1709436876941}', yt-remote-cast-installed: '{"data":"true","creation":1709436877399}', yt-remote-session-name: '{"data":"Desktop","creation":1709436876941}', yt-remote-cast-available: '{"data":"false","creation":1709436877400}', yt-remote-fast-check-period: '{"data":"1709437176941","creation":1709436876941}', …}IndexedDB存储方式
IndexedDB 是一种底层 API,用于在客户端存储大量的结构化数据(也包括文件/二进制大型对象(blobs))。该 API 使用索引实现对数据的高性能搜索。虽然 Web Storage 在存储较少量的数据很有用,但对于存储更大量的结构化数据来说力不从心。而 IndexedDB 提供了这种场景的解决方案。
IndexedDB 是一个事务型数据库系统,类似于基于 SQL 的 RDBMS。然而,不像 RDBMS 使用固定列表,IndexedDB 是一个基于 JavaScript 的面向对象数据库。IndexedDB 允许你存储和检索用键索引的对象;可以存储结构化克隆算法支持的任何对象。你只需要指定数据库模式,打开与数据库的连接,然后检索和更新一系列事务。
区别
关于cookie、sessionStorage、localStorage三者的区别主要如下:
存储大小:cookie数据大小不能超过4k,sessionStorage和localStorage虽然也有存储大小的限制,但比cookie大得多,可以达到5M或更大
有效时间:localStorage存储持久数据,浏览器关闭后数据不丢失除非主动删除数据; sessionStorage数据在当前浏览器窗口关闭后自动删除;cookie设置的cookie过期时间之前一直有效,即使窗口或浏览器关闭
数据与服务器之间的交互方式,cookie的数据会自动的传递到服务器,服务器端也可以写cookie到客户端; sessionStorage和localStorage不会自动把数据发给服务器,仅在本地保存
应用场景
标记用户与跟踪用户行为的情况,推荐使用cookie 适合长期保存在本地的数据(令牌),推荐使用localStorage 敏感账号一次性登录,推荐使用sessionStorage 存储大量数据的情况、在线文档(富文本编辑器)保存编辑历史的情况,推荐使用indexedDB