夯实基础——本地存储

207 阅读6分钟

看面试题的时候,经常会有一些关于本地存储的问题,之前都一直知道个大概,但是说不出个所以然来,因此决定写一篇博客,记录一下本地存储的知识点。

三种存储方式

众所周知,浏览器共有三种存储方式

  • cookie
  • sessionStorage
  • LocalStorage

下面分析一波各种的优缺点

cookie

让我们来看看MDN上的解释

cookie是服务器发送到客户端并保存在本地的一小块数据,它会在浏览器下一次向同一个服务器再发起请求的时候被携带到服务器上。

通常,cookie用来告知服务器两个请求是否来自同一个服务器,比如保持用户的登陆状态。

cookie主要用于三个方面

  • 会话状态管理:比如用户登陆状态,购物车,游戏分数等需要记录的数据
  • 个性化设置:比如用户自定义的主题,设置等
  • 浏览器行为跟踪:比如跟踪分析用户行为等

cookie曾经是客户端数据存储的王者,但这是迫不得已的方案。而现在各种浏览器都开始支持各种各样的存储方式,cookie就逐渐被淘汰了。因为服务器指定cookie后,客户端的每次请求都会带上一段cookie数据,带来额外的性能开销。

使用方法(CURD)

增加

// 客户端设置
document.cookie = '名字=值'
document.cookie = 'username=admin'

注意:客户端可以设置cookie的下列选项:expires、domain、path、secure(这个是有限制的:只有在https协议的网页中,客户端设置secure类型的cookie才能成功),但是无法设置HtppOnly选项。

// 服务端设置
Set-Cookie:消息头是一个字符串,其格式如下
Set-Cookie:value[; expires=date][; domain=domain][; path=path][; secure]

注意:服务端可以设置cookie的所有选项:expires、domain、path、secure、HttpOnly。通过Set-Cookie指定的这些可选项只会在客户端使用,而不会被发到服务器端。

删除

把要删除的cookie的过期时间设置成已过去的时间即可,注意其他选项需要和旧cookie保持一致

修改

修改一个cookie,只需要重新赋值即可,旧的值会被新的的值所覆盖。注意其他选项要和旧cookie保持一致。

查询

通过document.cookie获取到当下网站的cookie时,会得到字符串形式的值,包含了当前网站下的所有cookie。这个字符串的形式是这样的:所有cookie通过一个分号加空格的形式串联起来,比如username=admin; password=123456

可选项

过期时间

如果要长时间存放一个cookie,需要在设置cookie的同时给它设置一个过期时间,不设置的话cookie会在关闭客户端的时候自动销毁。

一个常见的例子:设置cookie保存5天
let exdate = new Date()
exdate.setDate(exdate.getDate() + 5)
document.cookie = 'username=admin' + '; expires=' + exdate.toGMTString()

注意:expires是http/1.0协议中的选项,在新的http/1.1协议中,expires已经由max-age选项代替,两者的作用都是限制cookie的有效时间。

域(domain)

domain指定了cookie将要被发送到哪里。默认情况下,domain会被设置为创建该cookie的页面所在的域名,所以当给相同域名发送请求时cookie会被发送到服务器。

安全性(secure)

cookie信息都是通过HTTP连接传递数据,这种传递方式很容易被查看,所以cookie存储的信息容易被窃取。当传递重要信息时,需要加密的数据传输。

secure选项可以设置cookie只在安全的请求中才能发送,当请求是HTTPS或其他安全协议时,包含secure选项的cookie才能被发送到服务器。

请注意:把cookie设置成secure,只保证了cookie和服务器之间的数据传输过程加密,但是保存在本地的cookie文件并没有加密。而且设置了secure也并不代表他人不能看到本地保存的cookie信息。因为cookie这个机制本身就是不安全的,这个问题无解,只能规范机密且敏感的信息绝不能在cookie中传输。

HttpOnly

HttpOnly用于设置cookie能否被js访问,默认情况下,cookie不会有HttpOnly选项(为空),因此客户端可以通过js代码进行访问这个cookie(CURD),而带上HttpOnly后,客户端则无法获取这个cookie

LocalStorage

MDN的解释再次走起

LocalStorage允许你访问一个Document源的对象Storage,存储的数据将保存在浏览器会话中。localStorage类似于sessionStorage,但区别在于:localStorage的数据可以长期保存,而sessionStorage的数据在客户端关闭后自动销毁。

LocalStorage中的键值对是以字符串的形式存储的,数值转换后可获得js对象。

优缺点

  • 生命周期:持久化,除非你主动删除,否则永不过期
  • 数据在同一个域中是共享的
  • 大小:在5m左右(每个浏览器不同)
  • 非IE浏览器中的LocalStorage可以本地打开,IE浏览器要在服务器打开
  • localStorage本质是对字符串的读取,如果存储内容过多则会消耗内存空间,导致页面卡顿
  • localStorage收同源策略的限制

使用方法(CURD)

增加

localStorage.setItem('username', 'admin')

删除

// 删除一个
localStorage.removeItem('username')
// 删除全部
localStorage.clear()

修改

重新赋值即可更新

查询

const value = localStorage.getItem('username') // 获取值
const key = localStorage.key[0] // 获取第一个键名

SessionStorage

让我们看看神奇的MDN

sessionStorage和localStorage类似,最大的区别在于:sessionStorage的数据会在页面访问结束之后销毁。

  • 页面会话在浏览器打开期间一直保持,并且刷新和恢复页面仍然会保持原来的会话。
  • 在新标签或窗口打开一个页面时会赋值顶级浏览会话的上下文作为新会话的上下文。
  • 打开多个相同URL的Tabs页面,会创建各自的sessionStorage。
  • 关闭对于浏览器的Tab,会清楚对于的sessionStorage。

使用方法(CURD)

参考localStorage的使用方法,把localStorage改成sessionStorage即可。

其他的前端存储方式

web SQL database

这是一个关系型数据库,操作过程过于麻烦

indexedDB

indexedDB是一个低级API,用于客户端存储大量结构化的数据(比如文件)。这个API使用索引来实现对该数据的高性能搜索。对于处理存储量大的结构化数据更有用。

然而实际情况是,如果有很多数据的话,也不会全传给客户端;如果只有一点数据的话,使用indexedDB又显得有点小题大做,因此是否使用还是要看业务场景。