1.背景
- 在HTML4.01中,想要在浏览器中存储用户的数据时,我们一般只能用Cookie来实现,不过Cookie有很多限制
- 大小限制:最大4KB
- 数量限制:每个站点只允许存储20个Cookie,如果想要存储更多Cookie,则要把旧的Cookie删除掉
- 性能浪费:每次HTTP请求都要携带Cookie,即使不会使用到Cookie
- 是否支持跨域:需要遵守浏览器的“同源策略(域名、端口、协议一致)”,本身不支持跨域,如果要跨域,需要特殊处理
- 因为Cookie的种种限制,HTML5为我们提供了3种全新的存储方法
2.localStorage(本地存储)
- 用于永久存储客户端的少量数据
- 所用到的方法(五种)
setItem(key,value) | 保存数据 |
getItem(key) | 获取数据 |
removeItem(key) | 移出数据 |
clear() | 移出全部数据 |
key(n) | 获取第n个值,n为整数 |
- 特点:(必须认真记忆)
- 每个域名可以保存5MB数据
- 关闭浏览器该存储方式存储的内容不会丢失
- 该存储方式存储的数据是永久的,不会丢失,除非自行删除
- 不同浏览器的localStorage数据是不可以共用的
- 该存储方式的存储数据存储在本地电脑中,而不是存储在服务器中
- localStorage和sessionStorage都是window对象下的子对象
- 本身不支持跨域共享数据,如果要跨域,需要特殊处理
- 用途:
- 留言板
- 存储些不用跟服务器交互的简单数据
3.sessionStorage(窗口存储)
- 用于临时保存客户端的少量数据
- 该存储方式所用的方法跟localStorage一模一样
- 特点:
- 该存储方式存储的内容在关闭窗口的时候就会被清除,不会永久存储
- localStorage和sessionStorage都是window对象下的子对象
- 通过跳转的页面可以共享sessionStorage值
- 用途:
- 存储
4.indexedDB(数据库)
- 用于永久保存客户端的大量数据
- 该数据库是HTML5新增的一种存储在客户端本地的NoSQL数据库,用于在本地存储大量数据
- indexedDB是“对象型数据库”,而不是“关系型数据库”,它的功能相对于传统的数据库来说会简单很多
- HTML5标准废除了 Web SQL Database
- 使用:
- 创建数据库(open方法来创建或打开数据库,包含两个事件)
- 第一个参数为数据库名字,第二个参数为数据库版本号(版本号可以随意取)
- onerror事件:请求失败时触发的事件
- onsuccess事件:请求成功时触发的事件
- 通过e.target.result可以获取到IDBDatabase对象(就是刚创建的数据库),增删改查都是基于这个对象来完成的
- 创建数据库(open方法来创建或打开数据库,包含两个事件)
<script>
let request = window.indexedDB.open('stu','1.1'); // 创建数据库
request.onerror = function(){ // 创建失败事件
console.log('创建数据库失败')
}
request.onsuccess = function(e){ // 创建成功事件
console.log('创建数据库成功')
let db = e.target // e.target 指向该请求(也就是指向创建的数据库)
console.log(db.result); // 获取IDBDatabase对象,这个对象很重要,我们可以通过该对象可以获取数据库的各种信息如,数据库名、版本号等
}
</script>
TIP:
区别e.target和this
当一个元素里面包裹了子元素,那么点击子元素会触发“冒泡”,这个时候this指向绑定的父元素,而非子元素
而就算存在“冒泡”行为,但是e.target依旧指向点击的那个子元素
总结:用e.target会指向点击的那个元素,而this则不一定,可能会指向别的元素
如下图
-
- 删除数据库(使用indexedDB对象的deleteDatabase()方法)
- 有一个参数,该参数为想要删除的数据库的名字
- 跟open方法一样,deleteDatabase方法会有两个事件(onerror、onsuccess事件)
- 删除数据库(使用indexedDB对象的deleteDatabase()方法)
5.操作“对象仓库”(表)
- SQL中,有库就有表,但是indexedDB是没有表这个说法的,而是“对象仓库(Object Store)”来代替
- 时刻记住:indexedDB中,“对象仓库”就是一张表
- 创建一张“表”
- 在indexedDB中,我们可以通过IDBDatabase对象的createObjectStore()方法来创建“对象仓库”(也就是“表”)
- 一个事件(onupgradeneeded事件)
- 请求对象request除了有onerror和onsuccess事件外,还有一个onupgradeneeded事件,它表示版本号更新时触发的事件。对于对象仓库的创建,我们一般都在这个事件里面完成
- 在这个事件里面要做的事情
- 获取IDBDatabase对象(通过e.target.result)
- 利用db.objectStoreNames.contains("对象仓库名")来判断,新建的“对象仓库”是否已经存在
- 如果存在,则报存在,如果不存在,利用db.createObjectStore("对象仓库名",{keyPath:"主键名"})创建“对象仓库”
- 利用我们实现准备好的数据,进行数据存储
<script>
let request = window.indexedDB.open('wtu','1.0');
request.onerror = function(){
console.log('创建数据库失败');
}
request.onsuccess = function(){
console.log('创建数据库成功');
}
request.onupgradeneeded = function(e){ // request的第三个事件,用于创建一个“对象仓库”,也就是一张表
let db = e.target.result // 获取 IDBDatabase对象
// 如果数据库中不包含该对象仓库,也就是没有这张表,则创建新的对象仓库,也就是新建一张表
if(!db.objectStoreNames.contains('stu_01')){ // db.objectStoreNames.contains('对象仓库') // contains检测对应字符串里面是否包含指定字符串或者字符
// 创建表的格式:db.createObjectStore('对象仓库名',{keyPath:'主键名'})
let store = db.createObjectStore('stu_o1',{keyPath:'id'}) // 注意:这个keyPath的p是大写
for(let i = 0;i < store.length;i++){
let addRequest = store.add(data[i]);
// addRequest对象也有两个事件
addRequest.onerror = function(){
console.log('创建对象仓库失败');
}
addRequest.onsuccess = function(){
console.log('创建对象仓库成功')
}
}
}else{
console.log('该对象仓库已经存在')
}
}
</script>
6.对象仓库的“增删改查”
- 当我们要使用对象仓库来进行增删查改的时候,我们都需要开始一个事务,事务就是“一组操作步骤”
- 记住一点:凡是涉及对象仓库的增删查改,都是使用事务来处理的
- 凡是对象仓库的增删改查都是在请求成功(request.onsuccess)里面进行操作
- 增(add)
- 增(add)与创建对象仓库很类似,但是很不一样
- 增加数据使用的是transcation()方法,开启事务来执行,而创建新表使用的是createObjectStore()方法
<script>
let data = [
{
id:1004,
name:'zs',
sex:'男'
},
{
id:1005,
name:'ls',
sex:'女'
},
{
id:1006,
name:'kangkang',
sex:'男'
}
]
let request = window.indexedDB.open('stu','1.0');
request.onerror = function(){
console.log('创建数据库失败');
}
request.onsuccess = function(e){
// 1.获取IDBDatabase对象,记住一切indexedDB都是基于这个对象,所以必须先获取
let db = e.target.result
// 2.开启事务(格式:db.transaction(['对象仓库名'],'事务模式')) 事务模式有两种:1.read 只读 2.readwrite 读写
let transaction = db.transaction(['stu_o2'],'readwrite');
// 3.连接到对象仓库
let store = transaction.objectStore('stu_o2');
// 4.添加新数据
for(let i = 0;i < data.length;i++){
let dataRequest = store.add(data[i])
dataRequest.onerror = function(){
console.log('添加失败')
}
dataRequest.onsuccess = function(){
console.log('添加成功')
}
}
}
</script>
- 删(delete)
let request = window.indexedDB.open('stu','1.0');
request.onerror = function(){
console.log('创建数据库失败');
}
request.onsuccess = function(e){
// 1.获取IDBDatabase对象,记住一切indexedDB都是基于这个对象,所以必须先获取
let db = e.target.result
// 2.开启事务(格式:db.transaction(['对象仓库名'],'事务模式')) 事务模式有两种:1.read 只读 2.readwrite 读写
let transaction = db.transaction(['stu_o2'],'readwrite');
// 3.连接到对象仓库
let store = transaction.objectStore('stu_o2');
let dataRequest = store.delete(1001)
dataRequest.onerror = function(){
console.log('删除数据失败');
}
dataRequest.onsuccess = function(){
console.log('删除数据成功')
}
}
- 查(get)
let request = window.indexedDB.open('stu','1.0');
request.onerror = function(){
console.log('创建数据库失败');
}
request.onsuccess = function(e){
// 1.获取IDBDatabase对象,记住一切indexedDB都是基于这个对象,所以必须先获取
let db = e.target.result
// 2.开启事务(格式:db.transaction(['对象仓库名'],'事务模式')) 事务模式有两种:1.read 只读 2.readwrite 读写
let transaction = db.transaction(['stu_o2'],'readwrite');
// 3.连接到对象仓库
let store = transaction.objectStore('stu_o2');
let dataRequest = store.get(1002)
dataRequest.onerror = function(){
console.log('查询数据失败');
}
dataRequest.onsuccess = function(){
console.log(this.result)
}
}
- 改(put)
let request = window.indexedDB.open('stu','1.0');
request.onerror = function(){
console.log('创建数据库失败');
}
request.onsuccess = function(e){
// 获取IDBDatabase对象,记住一切indexedDB都是基于这个对象,所以必须先获取
let db = e.target.result
// 开启事务(格式:db.transaction(['对象仓库名'],'事务模式')) 事务模式有两种:1.read 只读 2.readwrite 读写
let transaction = db.transaction(['stu_o2'],'readwrite');
// 连接到对象仓库
let store = transaction.objectStore('stu_o2');
// 需要修改的数据
let value = {
id:1002,
name:'hd',
sex:'女'
}
let dataRequest = store.put(value) // 将表中对应id的值修改成我们传过去的
dataRequest.onerror = function(){
console.log('修改数据失败');
}
dataRequest.onsuccess = function(){
console.log("修改数据成功")
}
}
- 清空(clear)
let request = window.indexedDB.open('stu','1.0');
request.onerror = function(){
console.log('创建数据库失败');
}
request.onsuccess = function(e){
// 获取IDBDatabase对象,记住一切indexedDB都是基于这个对象,所以必须先获取
let db = e.target.result
// 开启事务(格式:db.transaction(['对象仓库名'],'事务模式')) 事务模式有两种:1.read 只读 2.readwrite 读写
let transaction = db.transaction(['stu_o2'],'readwrite');
// 连接到对象仓库
let store = transaction.objectStore('stu_o2');
let dataRequest = store.clear();
dataRequest.onerror = function(){
console.log('删除数据失败');
}
dataRequest.onsuccess = function(){
console.log('删除数据成功')
}
}
7.总结
- localStorage、sessionStorage、Cookie的区别
- localStorage、sessionStorage的操作方法是一模一样的
setItem(key,value) | 保存数据 |
getItem(key) | 获取数据 |
removeItem(key) | 移出数据 |
clear() | 移出全部数据 |
key(n) | 获取第n个值,n为整数 |
- localStorage、sessionStorage是window下的子对象,所以利用 window.localStorage或者localStorage就能获取到localStorage对象,之后就可以进行操作了(sessionStorage同理)
- indexedDB数据库
- 获取数据库
- window.indexedDB
- 创建数据库(获取库下的操作)
- open()方法创建数据库或打开数据库
- open方法有两个参数,第一个为创建的数据库名称,第二个是版本号(版本号随意写)
- 对应的库一般取名为request,理解为请求,请求对象有三个事件
- onerror事件:操作错误事件
- onsuccess事件:操作成功事件
- onupgradeneeded事件:表示request对象更新时触发的事件
- open()方法创建数据库或打开数据库
- 获取IDBDatabase对象(一般命名为db)
- e.target.result
- 删除数据库(获取库下的操作)
- deleteDatabase(数据库名)
- 对应有两个事件
- onerror事件
- onsuccess事件
- 创建"仓库对象"(表)(表一般用store来命名变量)
- 创建表一般需要在request第三个事件upgradeneeded下进行
- 基于IDBDatabase对象的createObjectStore(“对象仓库名”,{keyPath:'主键名'})方法来创建表,若是没有主键名,那可以省略第二个参数的书写
- 利用 IDBDatabase对象下的 objectStoreNames.contians("对象仓库名")来判断是否有这个表
- 基于表下的四个方法:增删查改(在事件onsuccess下进行)
- 而增删查改都需要用到事务来解决
- 开启事务
- 利用transaction()方法来开启事务(得到事务对象)
- let transaction = db.transaction(["对象仓库名称"],"事务模式") // 事务模式有两种:1.readwrite 2. read
- 连接对象仓库(将事务与表建立连接)
- 利用事务对象的 objectStore()方法 来连接对象仓库
- let store = transaction.objectStore("对象仓库名称")
- 连接完成之后,可以对表进行增删查改等操作了
- 增:add(提前准备好的数据)
- 删:delete(“主键名”)
- 查:get(“主键名”)
- 改:put(提前准备好的数据)
- 清空:clear()
- 获取数据库