Description
一、什么是本地存储
- 客户端数据的存储
本地存储可以使用在哪里
- 用户临时登录信息,用户页面配置,当前临时信息等
- 一些东西用户想要存起来,下次访问可以继续使用,但是服务器没必要浪费空间来存这些信息,此时就可以应用本地存储,存放在用户本地
二、H5 之前如何实现本地存储
Cookie:
- http 请求头上会带着,安全问题
- 大小为 4k
- 主 Domain 污染
它比较常用的一个应用场景就是判断用户是否登录,比如登录某个网站可以看到“记住密码”,这通常就是通过在cookie中存入一段辨别用户身份的数据来实现的。针对登录过的用户,服务器端会在他登录时往 Cookie 中插入一段加密过的唯一辨识单一用户的辨识码,下次只要读取这个值就可以判断当前用户是否登录啦。
- 优点:兼容性最好,几乎所有的浏览器都支持
- 缺点:大小限制非常小,而且每次发送 HTTP 请求,请求头里会带着 Cookie 的信息,会带来安全问题
因为 cookie 会被带入 http 的请求内容中,如果大量的使用,请求包可能会越来越大,导致请求速度慢从而影响用户体验,所以 cookie 当然是能精简就精简。
cookie可以手动设置,也可以由服务器产生,当客户端(浏览器)向服务器发送请求,服务器会反馈一些信息给客户端,这些信息的 key / value 值被浏览器作为文件保存在客户端特定的文件夹中。
cookie 在浏览器存储形态,以百度为例:
// 存cookie
let setCookie = (name, value, times) = > {
let date = new Date()
data.setDate(data.getDate() + times)
document.cookie = name + '=' + value + ';expires=' + date
}
// 取cookie
let getCookie = (name) => {
let cookies = document.cookie
let cookieArr = cookies.split(';') || []
if(!cookieArr.length) return ''
for(let i = 0; i < cookieArr.length; i++) {
let arr = cookieArr[i].split('=')
if (name == arr[0] ) {
return arr[1]
}
}
return false
}
// 删除 cookie
let removeCookie = (name) => {
// 通过建立 cookie 的时间设置,将时间设置提前一天,从而强行让 cookie 失效,最后达到删除cookie 的目的
setCookie(name, '', '-1')
}
三、基于 HTML5 规范的 Web Storage
HTML5 提供了两种在客户端存储数据的新方法:
- sessionStorage 会话存储
- localStorage 本地存储
Web Storage 存储解决了 cookie 带来的一些限制:
- 解决4K的大小问题
- 解决请求头常带存储信息的问题
- 解决关系型存储的问题
- 跨浏览器
Web Storage 本地存储,数据不是由服务器请求传递的,从而它可以存储大量的数据,而不影响网站的性能。
比如在客户端保存一些用户行为或数据,如果遇到一些内容特别多的表单,为了优化用户体验,我们可以把表单页面拆分成多个子页面,然后按步骤引导用户填写,这时 sessionStorage 的作用就发挥出来了。或从接口获取的一些短期内不会更新的数据,我们也可以利用Web Storage来存储。
1、sessionStorage 临时存储神器
- 优点:临时,关闭页面标签自动回收,不同的两个标签页面的 sessionStorage 是不共享的
- 缺点:临时,因为是临时所以不能存储持久化的东西
2、localstorage 永久级别的存储
- 优点:兼容性中等,几乎现代的浏览器都支持,没有过期时间限制,永久存储,永不失效,即只要浏览器不卸载,数据就会一直存在,除非手动删除
- 缺点:存在大小限制,IE9,IE10 不支持
- localstorage 过期时间限制代码如下:
set (key, val) {
const curTime = new Date().getTime()
localStorage.setItem(key, JSON.stringify({
data: val,
time: curTime
}))
},
get (key) {
const data = localStorage.getItem(key)
const dataObj = JSON.parse(data)
if (new Date().getTime() - dataObj.time < 0) {
console.log('expires')
} else {
console.log('expir data = ' + dataObj.data)
localStorage.removeItem(key); // 缓存过期,清除缓存
}
}
3、localStorage 和 sessionStorage 比较
- 相同:大约 5MB(不同浏览器有差异),操作简单,类似 key / value 的存储方式;挂载在 window 对象下;
- 不同: 保存数据的生命周期不同:localStorage 里面存储的数据没有过期时间设置,在浏览器打开期间一直保持,并且重新加载或浏览器关闭再打开仍可以获取,而存储在 sessionStorage 里面的数据在页面会话结束时会被清除;localStorage 的数据不能跨浏览器获取,sessionStorage 不能跨页面交互,仅在当前页面中有效。
4、属性和方法介绍:
- length 获取存储数据的数量
- 除了 length 属性以及自定义属性外,其他的属性和方法都在原型中(注:obj 为 localStorage 或 sessionStorage):
key(index)
:获取存储数据中的第index
个键名obj.setItem(key, value) || obj.key = value || obj[key] = value
:存储数据value
的键名为key
,如果键名存在,则会覆盖对应的值obj.getIem(key) || obj.key || obj[key]
:获取指定键名key
对应的值obj.removeItem(key)
:移除指定键名key
对应的数据obj.clear()
:清除本地存储中的所有数据
5、都可以存储什么内容呢?
- 数组、json数据、图片、脚本、样式文件
- 存储图片的实现如下:
setImg (key) {
const img = document.createElement('img')
img.src = './1323_2071n.png'
img.addEventListener('load', function () { // 当图片加载完成的时候触发回调函数
const imgCanvas = document.createElement('canvas')
const imgContext = imgCanvas.getContext('2d')
// 确保 canvas 元素的大小和图片尺寸一致
imgCanvas.width = this.width
imgCanvas.height = this.height
// 渲染图片到canvas中
imgContext.drawImage(this, 0, 0, this.width, this.height)
// 用 data url 的形式取出
const imgAsDataURL = imgCanvas.toDataURL('image/png')
// 保存在本地存储中
try {
localStorage.setItem(key, imgAsDataURL)
} catch (error) {
console.log(error)
}
})
},
getImg (key) {
const srcStr = localStorage.getItem(key)
const imgObj = document.createElement('img')
imgObj.src = srcStr
document.getElementById('body').appendChild(imgObj)
}
如果一些图片不经常更改,存在localstorage,用户第二次访问的时候能很快访问,但如果图片资源很大,就比较费空间了。
6、使用注意事项:
-
使用前要判断浏览器是否支持:
移动端的浏览器,比如 IOS 如果把无痕模式打开,是不能访问 localstorage的。还有些浏览器,是可以访问localstorage 存储的对象,但是存储的时候会报错,这时可以在 localstorage set 时进行一个异常捕获,如果捕获到异常则浏览器不支持 localstorage -
写入数据时候,需要异常处理,避免超出容量抛错:
try catch 如果超出存储大小,可以使用一些算法,比如 LRU,FIFO 来处理旧数据 -
避免用它们存储系统中的敏感数据:
不是什么数据都适合放在 cookie、localStorage、sessionStorage 中的,因为只要打开控制台,就可以随意修改它们的值,如果网站中的代码存在 xss 注入的风险,它们就能对你的存储数据肆意妄为。 -
过期控制:
localstorage 没有过期时间限制,如果需要有过期限制,需要自己添加过期的业务处理机制 -
key的唯一性:
如果有重复key,会被覆盖 -
子域名之间不能共享存储数据
四、indexedDB Database
- 一种能在浏览器中持久的存储结构化数据的数据库,并且为 web 应用提供了丰富的查询能力
- 存储结构:
indexedDB 是按域名分配独立空间,一个独立域名下可以创建多个数据库,每个数据库可以创建多个对象存储空间(表),一个对象存储空间可以存储多个对象数据
简言之,indexedDB 提供了类似数据库风格的数据存储和使用方式,类似 NoSQL,很强大,支持所有、事物处理和健壮的查询功能。当需要存储大量数据时,indexedDB 就明显的更适合了。