前端存储实例,cookie,localStorage 和 sessionStorage的方案比较

215 阅读3分钟

参考:解决浏览器存储问题,不得不了解的cookie,localStorage和sessionStorage

需求来源

这个需求的背景是一个内部系统(技术栈是 react),有主页和详情页两个页面。从主页打开详情页,是通过新开一个标签页的方式实现的(window.open())。

某日,产品想在这个内部系统上加个功能,统计访问次数,需要前端在用户访问此系统时给后端发个请求。具体要求是:

  • 直接进入首页或者详情页算一次访问;
  • 首页退出重进算一次访问;
  • 首页、详情页刷新不算;
  • 从首页点开详情页不算;
  • 关掉详情页、回到首页也不算。

解决方案探索

一开始打算用 store 里存储变量(记录是否是首次访问)的方式来解决,但是由于主页和详情页在两个标签页上,所以不能用这种方法。

下面就开始考虑采用前端存储的方法来实现:

cookie

参考:HTTP cookies

Cookie 的生命周期可以通过两种方式定义:

  • 会话期 Cookie 是最简单的 Cookie:浏览器关闭之后它会被自动删除,也就是说它仅在会话期内有效。会话期Cookie不需要指定过期时间(Expires)或者有效期(Max-Age)。需要注意的是,有些浏览器提供了会话恢复功能,这种情况下即使关闭了浏览器,会话期Cookie 也会被保留下来,就好像浏览器从来没有关闭一样,这会导致 Cookie 的生命周期无限期延长。
  • 持久性 Cookie 的生命周期取决于过期时间(Expires)或有效期(Max-Age)指定的一段时间。

可以看出,持久性 cookie 肯定是不满足我们的需求的;而会话期 cookie 受浏览器的影响,不一定会自动清除。那么在页面关闭时强行清除 cookie 呢?也可以,但一般不这么干,因为一般来说,cookie 由服务端控制,是用来与服务端通信的,若前端需要存取,需要自行封装api。

另外,在已打开内部系统的情况下,若输入url直接打开首页/详情页,由于cookie的存在,不会将这次访问计数,这与需求要求的也不一样。

localStorage

相比于cookie,localStorage 就更不合适了:

  • 始终有效,窗口或浏览器关闭也一直保存,因此用作持久数据;
  • 同源窗口都会共享,并且不会失效,不管窗口或者浏览器关闭与否都会始终生效。

sessionStorage

sessionStorage 最吸引人的地方就在于其生命周期:

sessionStorage 和 标签页 同生同死。标签页关闭的时候,sessionStorage 就自动消失。而且每个标签页的 sessionStorage 是互相隔离的。

这就非常适合我们项目的这个需求,关闭标签页再次打开页面,又是一次新的访问。

但是,有一个非常重要的问题,从主页到详情页,不能算一次访问。那么,b页面(从a页面打开)能否读取到a页面的sessionStorage 呢?

参考:sessionStorage 的数据会在同一网站的多个标签页之间共享吗?这取决于标签页如何打开

可得结论:

a页面通过 a blank 方式打开的b页面,并不能继承a页面的sessionstorage;但是,a页面通过 window.open() 方法打开b页面,b页面是可以继承a页面的 sessionstorage 的。

而且,要注意,这里的继承仅是拷贝式的继承,打开b页面之后,改变a页面的 sessionstorage,不影响b页面;改变b页面的 sessionstorage,也不影响a页面。

通过空标签页输入url、直接打开的页面,与该浏览器之前打开的页面无关系,不会继承之前页面的 sessionstorage。

另外,通过a标签,在本标签页打开一个新页面(同域),新页面也会继承老页面的 sessionstorage。

结论

综上所述,使用 sessionStorage 可完成我们这个需求。