0


Cookie、Web Storage介绍

概述

Cookie、LocalStorage、SessionStorage、IndexDB这些作为浏览器的存储入口,也是经典的八股文了,本文再次冷饭热吃来介绍这些API,主要是因为在其他文章中看到了一些个人感觉有用的小知识点,所以在这记录一下,以便有序复习浏览。不多逼逼,开始正文。

Cookie

HTTP Cookie(也叫 Web Cookie 或浏览器 Cookie)是服务器发送到用户浏览器并保存在本地的一小块数据。浏览器会存储 cookie 并在下次向同一服务器再发起请求时携带并发送到服务器上。不同的请求方式对Cookie的处理不一样:
特性Fetch API (

credentials

)XMLHttpRequest (

withCredentials

)默认值

'same-origin'
false

默认行为同源请求中发送 Cookie;跨域不发送不发送 Cookie(无论同源还是跨域)发送同源 Cookie默认发送需要设置

withCredentials = true

发送跨域 Cookie需要设置

credentials: 'include'

需要设置

withCredentials = true

不发送 Cookie设置

credentials: 'omit'

默认行为

false

由于HTTP 协议是无状态的,对于服务器无法区分与其连接的客服端信息,所以引入了Cookie用以记录稳定的状态信息。Cookie是基于HTTP的,通常用于告知服务端区分两个请求是否来自同一浏览器。

Cookie主要有以下特点:

  • 这四种中唯一直接和服务器交互的存储方式
  • 可以设置Cookie.SameSite来阻止CSRF攻击。
  • 保存字符串类型的值,可通过序列号处理,大小为4KB
  • 没有设置Expires/Max-Age(过期时间/有效时间)时,默认是会话式的,关闭窗口时会删除Cookie记录
    SameSite 属性值描述适用场景StrictCookie 仅在同站点请求中发送,不会在任何第三方请求(如跨站点链接、表单提交、资源加载)中发送。高安全性场景,防止所有跨站点请求携带 Cookie,如敏感数据的保护。Lax(默认)Cookie 在同站点请求中发送,并在部分跨站点请求(如通过链接导航的 GET 请求)中发送。适用于大多数场景,平衡安全性和用户体验,防止大多数 CSRF 攻击。NoneCookie 始终发送,包括所有跨站点请求,必须配合
    Secure
    
    属性(即仅通过 HTTPS 发送)。需要跨站点访问 Cookie 的场景,如第三方嵌入内容或跨站登录。

    CSRF(Cross-site request forgery)跨站请求伪造:攻击者诱导受害者进入第三方网站,在第三方网站中,向被攻击网站发送跨站请求。利用受害者在被攻击网站已经获取的注册凭证,绕过后台的用户验证,达到冒充用户对被攻击的网站执行某项操作的目的。白话

    就是利用你的Cookie来冒充你和服务器进行通信,进行不好的操作
    

WebStorage

LocalStorage、SessionStorage统称为Web Storage(大小5M),而现代存储API包括: Web Storage、IndexedDB。 由于每次请求都会携带Cookie,随着Cookie存储数据过多时,会造成不必要的性能消耗。随着现代存储API出现之后,Cookie一般用于保存登录信息和服务器交互,其他数据推荐使用现代存储方式。

LocalStorage、SessionStoraged是通过 Window.sessionStorage 和 Window.localStorage 属性使用(更确切的说,在支持的浏览器中 Window 对象实现了 WindowLocalStorage 和 WindowSessionStorage 对象并挂在其 localStorage 和 sessionStorage 属性下)——调用其中任一对象会创建 Storage 对象,通过 Storage 对象,可以设置、获取和移除数据项。对于每个源 sessionStorage 和 localStorage 使用不同的 Storage 对象——独立运行和控制。
在这里插入图片描述

两者区别如下

  1. 持久性:- LocalStorage:数据持久化,直到手动删除。- SessionStorage:数据在浏览器会话结束时删除,浏览器关闭即失效。
  2. 数据共享:- LocalStorage:在同一源的所有标签页和窗口共享数据。- SessionStorage:仅在同一窗口或标签页内共享数据,不跨标签页。

多个tab间能否共享SessionStorage?

可能有的同学看到这里会疑问为什么会有这个问题,上面介绍了SessionStorage是会话式的,以

窗口/tab

进行分配空间,那在多个tab间肯定是不能共享的。

但是当那在当前页面打开控制台,然后进行以下操作:

  1. 在当前页面通过sessionStorage.setItem随意设置一个值,然后通过getItem获取,当然此时肯定会获取到设置的值。
  2. 然后继续在当前页面控制台输入Window.open('http://www.baidu.com')(任意地址都可以,本文以百度为例)
  3. 在跳转的新页面通过getItem获取,此时你会发现能获取到。呀,这就和之前理解的不一样的,从这里看sessionStorage好像也能共享?
  4. 然后在新的页面再次sessionStorage.setItem设置一个新值,并返回跳转前页面通过getItem访问,此时会返回null

到这里可能有的人就有些迷惑了,要明白为什么会这样,首先要理解

SessionStorage是会话式的

这句话的含义。我的理解上面通过在当前页面通过window.open新开一个页面的方式其实是当前页面会话的一个延续,此时延续的会话会

复制

当前会话的内容。注意

是复制而不是共享

这就是为什么在新的页面能访问而上一个页面无法访问的原因。同理不在控制台调整,在页面内通过

<a>

标签也能实现。

举例说明:
  • A页面点击超链接跳转到B页面,如果是target=“_self”,(默认就是_self),跳转是在同一个浏览器tab页面里面进行的,此时不管怎么操作session,在同一个tab里面两个页面的session都是一样的。
  • 如果target=“_blank”,也得分为两种情况:rel表示当前页面和跳转的目标页面具有什么关系。 - 如果a标签没有rel="opener"属性,此时不会携带session。- 如果a标签有rel="opener"属性,则适用前面的原则,即从A跳转到B是一个会话,B页面会复制A页面的 session,此时在B页面回退(因为是新tab打开,所以无法回退,只能是重新有一个a标签,点击之后打开新tab,同样适用前面A页面的点击跳转规则),即打开新的A页面A1,此时A1页面是复制的B页面的session,如果B页面的session是修改过的,那么A1就是复制的最新的B页面的session。
<a>

标签的

rel

属性指定了目标对象到链接对象的关系。而值为

opener

则创建一个辅助浏览上下文,可以理解为当前会话的延续。详细值可查看MDN

一句话总结:SessionStorage是会话性质的,同一个会话/会话的延续会复制session。

Web Storage是同步还是异步的?

我们知道LocalStorage保存在磁盘中,SessionStorage保存在内存中。通常情况下磁盘等IO设备为了不阻塞进程,都是异步IO的。那这么看来LocalStorage就是异步的了?

其实不是,在控制台执行下面代码:

sessionLocalstorage同理都是同步的
consttestLocalStorage=()=>{
    console.log("==========> 设置localStorage之前");
    localStorage.setItem('testLocalStorage','我是同步的');
    console.log("==========> 获取localStorage之前");
    console.log('=========获取localStorage', localStorage.getItem('testLocalStorage'))
    console.log("==========> 获取localStorage之后");}testLocalStorage()

可以看到输入是同步的,那这是为什么呢?
原因就是因为Js是单线程的,当通过js代码在访问 localStorage 时,浏览器提供的API接口通常会处于js执行线程上下文中直接调用。这意味着尽管硬盘是IO设备,当一个js执行流程访问 localStorage 时,它将同步地等待数据读取或写入完成,该过程中js执行线程会阻塞。

完整的流程

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 调用返回。所以

一般不要将大量数据保存在Storage中,避免长时间同步阻塞,影响体验

Web Storage有大小限制是因为同步阻塞吗?

主要原因如下:

  • 资源公平分享:同一用户可能会访问大量不同的网站,如果没有限制,随着时间的积累,每个网站可能会消耗大量的本地存储资源。这样会导致本地存储空间被少数几个站点占用,影响到用户访问其他网页的体验。限制大小可以确保所有网站都有公平的存储机会。
  • 防止滥用:如果没有存储限制,网站可能会滥用 localStorage,存储大量数据在用户的设备上,这可能导致设备存储空间迅速耗尽,也可能侵犯用户的隐私。
  • 性能限制:如之前提到的,localStorage 的操作是阻塞的。如果网站能够存储大量数据,就会加剧读写操作对页面性能的影响。
  • 存储效率:localStorage 存储的是字符串形式的数据,不是为存储大量或结构化数据设计的。当尝试存储过多数据时,效率会降低。
  • 历史和兼容性:5MB 的限制很早就已经被大多数浏览器实现,并被作为一个非正式的标准被采纳。尽管现在有些浏览器支持更大的 localStorage,但出于跨浏览器兼容性的考虑,开发者通常会假设这个限制。
  • 浏览器政策:浏览器厂商可能会依据自己的政策来设定限制,可能是出于提供用户更一致体验的角度,或者是出于管理用户数据的方便。

总结

本文主要介绍了Cookie、LocalStorage、SessionStorage三种存储机制,总结一下就是:

三者都只能保存字符串数据,并且都有大小限制。其中Cookie一般用于鉴权,LocalStorage将数据保存在磁盘中可以用于跨tab以及持久化访问,SessionStorage将数据保存在内存中,是会话式的,当在同一个会话或者会话延续时,可以访问Session。LocalStorage是共享,SessionStorage是复制。

参考文章

【前端缓存】localStorage是同步还是异步的?为什么?

标签: 前端

本文转载自: https://blog.csdn.net/weixin_44273311/article/details/142171717
版权归原作者 宇豪学习录 所有, 如有侵权,请联系我们删除。

“Cookie、Web Storage介绍”的评论:

还没有评论