25 客户端存储
写在前面 :IndexedD 索引暂时没有学习整理
cookies
限制
- cookies 与特定的域绑定 这个限制保证了 只能被认可的接受者接受 不可以被其他域访问
- 不要超过300个cookie
- 每个域的cookie总数不超过20个
- 每个cookie不能超过4096字节
- 每个域不能超过81920字节 🚶 不同浏览器存在差异 例如:
- 最新的IE 与 Edge 限制每个域不超过 50个cookie
- 最新的fireFox 限制每个域不超过 150个cookie
- 最新的Opera 限制每个域不超过 180个cookie
- Safari 和 Chrome 对每个域的cookie数没有限制 🖕 如果cookie 总数超过单个域 上限 浏览器会删除之前设置的cookie。浏览器之间会存在差异,避免不确定性,不要超出限制。
cookies的构成
- 名称: 唯一标识cookie 的名称,不区分大小写;
- 值: 存储 字符串值,值必须经过URL 编码。
- 过期时间: 何时删除cookie值 ;时间到了立即删除 未设置时间 会话结束删除 cookie
- 安全标志: 设置之后 只使用SSL安全连接的情况下 才会把cookie 发送到服务器。例如请求 https:// xxx 会携带 cookie http:xx则不会携带
- cookie 设置了secure 只能在SSL连接上发送
JavaScript中的 cookie
- 通过 document.cookie 设置; 例如:document.cookie ="name=value"
- 所有的值与名必须是URI编码; 必须使用decodeURIComponent() 解码;
- 简化繁杂操作 可以使用cookie.js
子cookie
一个键的值 对应多组键值关系的结构;例如:name=name1=value1&name2=value2&name3=value3;
实际开发中注意不要超出单个cookie大小
使用cookie 的注意事项
HTTP-only 的cookie ;可以在服务器或浏览器进行设置;只能在服务器读取
cookie 存储大量的信息 可能会影响 浏览器的性能;保存cookie越大 请求耗费时间越长;
cookie不要存放敏感数据 不安全 任何人都可以获取
web Storage
规范中的两个目标
- 提供在cookie 之外的存储会话数据途径
- 提供跨会话持久化存储大量数据机制
- 定义了两个对象:localStorage 和 sessionStorage
- localStorage 是永久的存储机制;sessionStorage 是跨会话的存储机制
storage类型
增加了如下方法
- clear():删除所有值;
- getItem(name):获取name的值;
- key(index):取得给定位置的名称;
- removeItem(name):删除给定name的名值对;
- setItem(name,value);设置给定name的value
sessionStorage 对象
只存储会话数据,只能保存数据到浏览器(当前页面)关闭;
存储的sessionStorage 不受页面刷新的影响;
sessionStorage 对象 与服务器会话紧密相关 运行本地文件不能使用;
存储在sessionStorage对象的数据 只能在最初的页面使用 再多页面程序用处有限;
添加数据 两种方式:
- sessionStorage.setItem("name","value") //使用setItem实现
- sessionStorage.name = value // 使用属性存储数据
所有现代浏览器实现存储写入 都是使用同步阻塞方式,因此数据会立即提交到存储;
获取属性 两种方式:
- sessionStorage.getItem('name')//通过 getItem实现
- sessionStorage.name //使用对象属性方式 获取
遍历所有值可以通过 for循环与 key()方法实现
删除属性
- sessionStorage.removeItem(name) 实现
- delete sessionStorage.name //对象方法实现
localStorage 对象
H5规范里localStorage对象取代了 globalStorage 作为浏览器持久化的存储数据的机制
想要访问同一个localStorage 对象 页面必须是同一个域(子域不可以)
- localStorage 也是 storage 的实例 所以同样可以使用 Storage 上的方法
localStorage 与 sessionStorage 区别
- localStorage 会保留数据 失效方式:只能用户主动清除缓存或通过JavaScript删除
- localStorage 数据 不受 重启浏览器 关闭标签的的影响
存储事件
每当 storage对象发生变化时就会触发 ‘storage’事件
触发方式
- 设置属性
- 删除属性
- 清除所有 数据clear()
事件对象 有如下四个属性:
- domain:存储变化对应的域
- key:被设置或者删除的键
- newVal:键被设置的的新值,若删除则为null
- oldValue:键变化之前的值
具体监听storage事件如下
javascriptwindow.addEventListener('storage',(event)=>{ console.log(event.domain) })
storage 事件 不会对 sessionStorage 与 localStorage 对象作区分 任何一个改变都会触发
限制
- 不同浏览器 给localStorage 和sessionStorage 设置了不同的空间限制
- 大多数会限制每个源5MB
IndexedDB
- IndexedDB 是现代浏览器中存储
数据化结构
的方案 - IndexedDB 是为了代替目前废除的 WebSQL Database API。
- 创建一套API 方便对象的存储与获取
- IndexedDB 几乎是完全异步的
- 绝大多数的IndexedDB 操作要求添加 onerror 和 onsuccess 事件处理程序 来确定输出
- 数据库
- 使用IndexedDB
- 调用 indexedDB.open()方法 ,并传入名称,名称存在则打开;不存在则创建并打开;并返回一个IDBRequest实例
- 实例上添加onsuccess 监听成功的回调函数
- 实例上添加onerror 监听失败的回调
- 可以通过event.target.result 得到当前的db对象
event.target.errrorCode
来存储出现问题的状态码
- 使用IndexedDB
- 对象存储
- 数据库不存在 open会创建一个数据库 然后触发 upgradeneeded事件
- 如果数据库存在 升级了版本号 也会触发upgradeneeded事件
- 可以在事件处理程序中更新数据库模式
- 事务
- 事务是通过带哦用数据库的transaction方法创建。例如:let transaction=db.transaction()
- transaction 不指定参数 数据库所有对象仅有只读权限
- bd.transaction('xx') 参数可以是一个字符串 或者字符串型数组,实现访问一个或多个对象存储
- 当 传入第二个参数 可以是**‘readonly’,‘readwrite’,‘versionchange’**;可读 、可写
- 有了事务引用 可以使用 objectStore()方法,传入对象存储名称来实现访问特定存储对象
- 可以使用 add put 添加或修改对象 ,get获取对象,delete删除,clear清除所有对象
- 事务的事件处理 onerror 和 oncompute
- 不可以在 oncompute中访问 get()请求返回的任何数据 仍需通过onsuccess 获取数据
- 插入对象
- add
- 事件变化都会触发 onsuccess onerror 其中一个事件
- 通过游标查询
- 可以实现获取多条数据
- 游标是 指向结果集的指针 ,与传统数据库查询方式不同 游标指向第一个结果后 并在接受指令前 不会主动查找下一条数据
- 需要在对象上 调用 openCursor()方法创建游标,同样创建完成会返回一个request 可以监听其onsuccess 和onerror 事件
- 此时request 保存的是*IDBCursor** 的实例,包含几个属性
- direction:字符串常量,表示游标的前进方向以及是否应该遍历所有重复的值。可能包括 next,nextunique,prev,prevunique;
- key:对象的键
- value:对象的值
- primaryKey:游标使用的键,可能是对象键或引用键
- 更新记录 update方法使用指定的游标对象更新当前指向的对象的值,同时会返回一个request对象 可以通过 onerror 和onsuccess 监听 结果
- 删除记录 delete方法来实现删除游标位置的记录,与update 类似
- 值得注意的是 当事务没有 删除与修改的权限时 会抛出错误
- 前面提到 默认情况下 游标只会创建一个请求 要创建下一次请求 必须调用以下方法
- continue(key):移动结果集的下一条记录 参数key可选的 无走向下一条,有则游标指向指定的键;
- advance(count):游标详情移动指定的count条记录
- 键范围
- 键范围 对应IDBkeyRange 的实例。
- 有四种方式指定键范围
- only(key) ;类似与直接访问对象存储并调用get(key);
- 定义结果集下限 ,下限表示游标开始的位置
- IDBRange.lowerBound(key,bool) //参数一key,参数二:true表示从key之后开始,false or 不传表示从key到结束
- 定义结果集上限 上限表示从头开始到key结束 第二个参数传递true不包含 key
- IDBRange.uppperBound(key,bool)
- 同时设定上下限 通过bound 来实现
- 参数1上限 ,参数2下限参,数3是否包含上限内容,参数4是否包含下限
- 例如 IDBRange.bound('007','ace',fasle,true) // ['007','ace')
- 定义完键范围 传给openCursor()方法就可以得到该范围的游标
- 设置游标方向
- openCursor 方法 实际上接受两个参数 ,参数1:IDBRange的实例,参数2 表示方向的字符串 默认方向是’next‘
- nextunique 游标跳过重复项
- 参数1 为null时,表示默认的额所有值
- 索引
- 🗡️ 暂时省略
- 并发问题
- 产生场景 不同浏览器标签打开同一个网页 可能一个尝试升级 另一个尚未就绪
- 解决办法
- 在第一次打开数据库时添加 onversionchange 事
- 同源标签将数据库打开时 将会执行回调 执行立即关闭数据库 以便完成数据库版本的升级
- 监听 同步处理
- 限制
- IndexedDB 数据库 是与页面源(协议、域名和端口)绑定的,信息不可以跨域
- 存储扣减每个源 都有自己独立的存储空间 firefox 限制 每个源50MB 移动端5MB chrome 时5MB,超出配额则请求用户许可;
- firefox 还有个限制 本地文件不能访问IndexedDB 数据库??。Chrome 没有限制
- 小结
- 数据没有加密,不适合存储安全数据