在说数据存储之前,我们先弄明白为啥要做存储,数据存储目的是为了减少网络资源的开销,提高客户端的性能和体验。通常利用存储来做一些登录信息的存储,静态资源的展示。客户端实现数据存储的方式也是多种多样的,像local storage,session storage,cookie,indexDB。下面我们来对比下他们的区别。
local(本地的)storage(存储),言下之意数据是存放在浏览器缓存文件下,和页面状态(打开,冻结,关闭)没半毛钱关系。就算怒关浏览器也无所畏惧。只有在手动清除缓存数据或文件才会被清除。缓存数据可以用storage的方法(setItem,getItem,removeItem)操作。那么storage缓存文件又放在那里呢?以chrome为例。在chrome地址栏输入chrome://version
,此时看到一大堆chrome的版本信息。
接着找到个人资料路径,打开它
再接着在该目录下可以看到Local Storage这个文件夹,是的,chrome的local storage 数据就放在这里
每当我们操作local storage的数据时,chrome就会在数据文件中插一条与当前域名绑定的数据。
虽说是本地缓存,但local storage的数据和域名是一一对应的(同源),就是说不能够跨域去取得这些数据。
另一个要关心的是local storage能够存储的数据量。官宣是5M,我们也可以拿每个1M的字节量量测试一下
在这里我们在同一个域名下插入6条,每条的量大概是1M,当插入到第6条时,看样子是进去了,接着把界面切换一下再回去,只剩下5条数据。5 * 1M = 5M。当然,这只是针对一个域名下,若切换到另一个域名,则重新计算。
local storage 的用法也很简单
localStorage.setItem(key,value) // 设置一对键值
localStorage.getItem(key) // 获取键为key的storage
localStorage.removeItem(key) // 移除建为key的storage
session(会话)storage(存储),会话也很好理解,即在交流通信时候的缓存。打个比方,当我们在谈钱的时候,这个对话里面是饱含着我们的深厚感情的,当谈钱结束后,甚至你是谁我都得好好想一下。
当打开了一个页面之后,这个页面就处在一个会话阶段,这时候session storage会陪伴你左右,此时你们感情暧昧着,直到创建该页面的标签关闭,session storage就被清除了,就像它从未认识你一样。
同样的,session storage也是和域名一一对应的。而关于它的存储量也是去到 5 M左右*(chrome)*
session storage 的用法也很简单
sessionStorage.setItem(key,value) // 设置一对键值
sessionStorage.getItem(key) // 获取键为key的storage
sessionStorage.removeItem(key) // 移除建为key的storage
cookie作为较早期的数据存储方式。它的用法和能力就没那么出众了。
首先在用法上,cookie的存储方式是url参数方式的字符串。不能像storage使用键的方式操作项。只能通过封装方法来实现同样功能。
其次cookie是作为请求头的字段发送给服务端,大小大约只有4KB,不适合存储大块数据。
好处是cookie在每次请求接口是都会自动附加到请求头中,而且能够设置过期时间,很多时候都作为用户凭证验证的选择。
cookie的增删改查只能通过document.cookie去操作
document.cookie // 获取所有cookie的字符集
document.cookie = '' // 利用赋值去改变cookie
虽然说local storage 和 session storage操作简单,能缓存的数据量也够用了,但作为storage的值是以字符串形式存储的,当遇上结构化的数据时(如object)只能通过解析|转换来进行存取。
而indexedDB提供了一个解决方案,可以保持结构化来存储大量数据,indexedDB 利用索引方式去检索数据,简单说耗时低。indexedDB的使用可以简化成下面几步
1.打开 | 创建数据库
2.创建存储(如果已创建, 跳过)
3.建立事务
4.执行操作
// 1.打开 | 创建数据库
const indexDB = window.indexedDB || window.webkitindexedDB
var request = indexDB.open('dbname', 1/*版本号*/)
var db = null
// 版本号不一致时触发upgradeneeded事件
request.onupgradeneeded = function(e) {
db = e.target.result
// 2.创建object store
let bookStore = db.createObjectStore('store', {
autoIncrement: true,
keyPath: /* 索引键字段 */ 'indexKey'
})
// 创建store的索引(字段)
bookStore.createIndex('title', 'title', { unique: false })
bookStore.createIndex('produce', 'produce', { unique: false })
bookStore.createIndex('author', 'author', { unique: false })
bookStore.createIndex('catelog', 'catelog', { unique: false })
}
request.onsuccess = () => {
db = e.target.result
// 要插入的对象
var newBook = {
indexKey: 'book tag',
title: 'Harry Potter',
produce: 'magic',
author: 'J.K.罗琳',
catelog: '1.2.3'
}
// 3.建立事务
// 若ObjectStore不存在会抛出异常,要在indexDB版本升级阶段创建 ObjectStore
let trans = res.transaction('store', 'readwrite'/*事务的操作权限*/)
trans.onerror = function(e){
// 捕获事务错误信息
console.log(trans.error);
}
// 指定要操作的 object store
let store = trans.objectStore('store')
// 4.执行操作
// 添加一条数据
var addRes = store.add(newBook)
addRes.onsuccess = function() {
console.log('add item success')
}
}
此时展开indexDB可以看到store下已经创建了刚添加的book
当然能存还不行呀,存了要取呀,钱在银行也不能只进不出呀。同样可以通过事务去取得数据
request.onsuccess = function(e){
db = e.target.result
var trans = db.transaction('store', 'readwrite')
// 注意:这里 get 传入 key 就是刚才创建 object store 的 key
var getRes = store.get('book tag')
getRes.onsuccess = function(e){
console.log('get item success')
console.log(e.target.result);
}
}
跑一圈代码,在console下可以看到我们要的 关于 book store 的所有信息的 object了
以上介绍了4中关于web数据存储的方法,下面我们对比一下这4个大家伙
特点/方法 | localStorage | sessionStorage | cookie | indexedDB |
---|---|---|---|---|
要求同源 | 是 | 是 | 是 | 是 |
大小限制 | 5M(chrome) | 5M(chrome) | 4K(chrome) | - |
操作方式 | 同步 | 同步 | 同步 | 异步 |
获取类型 | String | String | String | Object |
The End~