网页存储
网页存储
什么是web存储?
web存储指的是在web通信过程中,由客户端(如浏览器)对少量数据进行的本地存储(注:本文所说的是广义的web存储,而不单指Web Storage)。web存储类型主要包括古老的cookie,以及HTML5推出的sessionStorage、localStorage和indexedDB等
常见的浏览器的缓存有:cookie,localStorage,sessionStorage,indexDB.
cookie
简介:
key/value 单个cookie保存的数据不能超过4kb,每次访问都要传送cookie给服务器,可以设置过期时间,和域名绑定。
cookie在前端可以通过document.cookie获得,cookie本身是用encodeURIComponent编码的,因此,如果cookie中包含中文,需要用对应的decodeURIComponent解码才能得到对应值。
除了key和value外,每个参数还会携带其他几个属性,包括域、路径、失效时间、安全标志等,这些参数在使用document.cookie输出时无法看到,不过可以在调试工具中查看:
一般来说,cookie只用于保存与登录相关的信息,其中最重要的是服务端会话(session)对象的id。它不适合存储大量的数据,因为浏览器限制了每个cookie的大小不能超过4KB。此外,浏览器对单个域下cookie的数量也是有限制的,该数量因浏览器而异,对开发者来说,这个数量一般不要超过20个。
sessionStorage
简介:
key/value 关闭页面或浏览器后被清除,最大5MB,和域名绑定。
继承自Storge,可以通过window.sessionStorage
sessionStorage.setItem("name", "carter"); // 设置name: carter
sessionStorage.age = "24"; // 设置age: 24
sessionStorage.getItem("name"); // 获取name的值carter
sessionStorage.removeItem("name"); // 删除name
sessionStorage.clear(); // sessionStorage
- 遵循同源策略,即该存储只在同一个域下可以共享,跨域则无法访问,这样可以保证数据的安全性。
- sessionStorage拥有5MB的存储空间,并且只能保存字符串类型的数据,对于非字符串类型的数据,一般需要使用
JSON.stringify方法压缩成字符串,使用时再用JSON.parse进行解析。 - 失效时间:sessionStorage与页面会话是绑定的,当某个页面会话失效时,对应的sessionStorage就会被清除。需要注意的是,sessionStorage只在会话页面失效时才会失效。
- 有效范围:在不跨域的情况下,sessionStorage不可以跨页签生效,
localStorage
简介
key/value 一直存储于本地硬盘(浏览器中可以删除),一般数据最大5MB(各个浏览器不一样),和域名绑定。
- 失效时间:localStorage本身是不会失效的,即使关闭浏览器,下次再访问该网站仍然有效。localStorage没有提供直接设置失效时间的方法,我们需要使用一种特殊的策略来定期清除localStorage。
- 有效范围:在不跨域的情况下,localStorage可以跨页签生效,
indexDB
简介
key/object,可以存储对象,浏览器中的数据库,异步,支持事务,和域名绑定,存储空间大。
尽管5M的空间已经相对较大了,但仍然无法满足所有的前端存储需求。
这是因为前端数据缓存对web站点的性能提升是巨大的(它可以有效减少http数据传输量,而这通常是导致网站卡顿的最主要因素),因此越来越多的站点倾向于在前端存储更多的数据。localStorage和sessionStorage无法满足这样的需求,因为一方面,它们的容量只有5M大小;另一方面,由于是非结构化存储,当数据量较大时,它们的操作速度不够快。
为此,HTML5规范推出了前端的事务型数据库indexedDB。它可以存储大量的结构化数据,具有几乎可以媲美后端数据库的读写性能(当然,从功能和容量上远不及后端数据库)。
特点
- 键值对存储
- 异步
- 支持事务
- 同源限制IndexDB受到同源限制,
- 存储空间大,
- 支持二进制存储
使用indexedDB大概需要以下几个流程:
- 打开数据库:
var request = window.indexedDB.open(databaseName, version);
这样就可以打开或新建一个indexedDB数据库。当所传入的数据库名不存在时,就会新建一个数据库,否则将打开已有数据库。当省略了数据库版本号时,如果数据库已存在,则默认为当前版本,否则版本号为1。
-
注册处理事件
调用open方法后,返回的是一个
IDBRequest对象,通过向其注册error、success和upgradenedded事件,可以处理打开数据的结果。error表示数据库打开失败:
request.onerror = function(err){
console.log("数据库打开失败:" + err);
}
success表示数据库打开成功,此时可以执行数据库读操作:
request.onsuccess = function (event) {
let db = request.result;
console.log('数据库打开成功');
};
upgradeneeded表示数据库需要升级,不同于一般的后端数据库,indexedDB每次修改数据库的内容都必须升级数据库版本:
request.onupgradeneeded = function (event) {
db = event.target.result;
var objectStore;
if (!db.objectStoreNames.contains('person')) {
objectStore = db.createObjectStore('person', { keyPath: 'id' });
}
}
- 增删改查操作
🎃实例开始
- 新建数据库
新建数据库与打开数据库是同一个操作,如果指定的数据库不存在,就会新建,后续操作在upgradeneeded事件的监听函数里面完成。
- 新建对象仓库-》表
request.onupgradeneeded = function (event) {
db = event.target.result;
var objectStore;
if (!db.objectStoreNames.contains('person')) {
objectStore = db.createObjectStore('person',
// 自动创建主键
//{autoIncrement:true}
{ keyPath: 'id' }
);
}
}
解释:判断一个是否存在叫做person的表,N-》新增一张叫做Person的表格,主键为id。
- 新建索引
request.onupgradeneeded = function(event) {
db = event.target.result;
var objectStore = db.createObjectStore('person', { keyPath: 'id' });
objectStore.createIndex('name', 'name', { unique: false });
objectStore.createIndex('email', 'email', { unique: true });
}
- 新增数据
function add() {
var request = db.transaction(['person'], 'readwrite')
.objectStore('person')
.add({ id: 1, name: '张三', age: 24, email: 'zhangsan@example.com' });
request.onsuccess = function (event) {
console.log('数据写入成功');
};
request.onerror = function (event) {
console.log('数据写入失败');
}
}
add();
写入数据需要新建一个事务。新建时必须指定表格名称和操作模式("只读"或"读写")。新建事务以后,通过IDBTransaction.objectStore(name)方法,拿到 IDBObjectStore 对象,再通过表格对象的add()方法,向表格写入一条记录。
同时写入操作是一个异步操作,可以通过onsuccess与onerror控制不同的事件操作。
- 读取数据
function read() {
var transaction = db.transaction(['person']);
var objectStore = transaction.objectStore('person');
var request = objectStore.get(1);
request.onerror = function(event) {
console.log('事务失败');
};
request.onsuccess = function( event) {
if (request.result) {
console.log('Name: ' + request.result.name);
console.log('Age: ' + request.result.age);
console.log('Email: ' + request.result.email);
} else {
console.log('未获得数据记录');
}
};
}
read();
-
遍历数据
遍历表格中所有的数据,要是有指针对象IDBCursor。
function readAll() {
var objectStore = db.transaction('person').objectStore('person');
objectStore.openCursor().onsuccess = function (event) {
var cursor = event.target.result;
if (cursor) {
console.log('Id: ' + cursor.key);
console.log('Name: ' + cursor.value.name);
console.log('Age: ' + cursor.value.age);
console.log('Email: ' + cursor.value.email);
cursor.continue();
} else {
console.log('没有更多数据了!');
}
};
}
readAll();
- 更新数据
function update() {
var request = db.transaction(['person'], 'readwrite')
.objectStore('person')
.put({ id: 1, name: '李四', age: 35, email: 'lisi@example.com' });
request.onsuccess = function (event) {
console.log('数据更新成功');
};
request.onerror = function (event) {
console.log('数据更新失败');
}
}
update();
- 删除数据
function remove() {
var request = db.transaction(['person'], 'readwrite')
.objectStore('person')
.delete(1);
request.onsuccess = function (event) {
console.log('数据删除成功');
};
}
remove();
-
使用索引
索引的意义在于,可以让你搜索任意字段,也就是说从任意字段拿到数据记录。如果不建立索引,默认只能搜索主键(即从主键取值)。
新建表的时候,对name的字段建立了索引。
即可以通过name找到对应的数据记录。
var transaction = db.transaction(['person'], 'readonly'); var store = transaction.objectStore('person'); var index = store.index('name'); var request = index.get('李四'); request.onsuccess = function (e) { var result = e.target.result; if (result) { // ... } else { // ... } }
参考:
web存储
阮一峰的网站记录
总结:暂时只是记录一个基本概念,后期加上各个的不同点,以及每一个的使用场景。

浙公网安备 33010602011771号