最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 浏览器存储方式学习 cookie, session, localstorage, indexedDB

    正文概述 掘金(SoulReader)   2021-02-13   561

    浏览器存储方式

    • cookie: cookie相当于客户端和服务器之间进行信息交互的一个标识,每次客户端访问服务器的时候都会携带上cookie,这样服务器就可以知道是谁来访问了。

    • Storage: Storage 是专门为浏览器存储提供的数据存储机制,分为localStorage和sessionStorage, 保存的数据以键值对的形式存在,并且以文本格式保存

    • indexedDB: indexedDB是运行在浏览器上的非关系型数据库, 一般来说是没有存储上限的, 不仅可以存储字符串, 还可以存储二进制数据

    Cookie

    cookie的本职工作并非本地存储,而是维持状态,它是浏览器存储在用户机器上的一个小文本,大小不能超过4K

    cookie根据过期时间分为两类:会话cookie和持久cookie

    • 会话cookie是一种临时cookie,当用户退出浏览器,会话cookie就会被删除

    • 持久cookie则会存储在硬盘中,保存时间更长,浏览器关闭并不会删除cookie,通常持久性cookie会维护某一个用户周期性访问服务器配置文件或者登陆信息

    访问方式

    通过document.cookie来设置或获取cookie的值

    产生Cookie的服务器可以向set-Coolie响应首部添加一个domain属性来控制那些站点可以看到这个cookie

      Set-Cookie:name="losstie"domain="m.baidu.com"
    

    属性

    • path参数告诉浏览器cokie的路径,默认情况下,cookie属于当前页面

    • secure 设置里secure,cookie只有在https协议加密的情况下才会发送给服务端

    • HttpOnly 禁止javascript操作cookie(避免跨域脚本xss攻击,通过javascript的document.cookie 无法访问带有HttpOnly标记的cookie)

    第三方cookie

    第三方cookie就是cookie的域和地址栏中的域,这种cookie通常悲痛在第三方广告网站,用于跟踪用户的浏览记录,并根据手机的用户浏览习惯,给用户推送相关广告

    劣势

    • cookie 存储信息少,不能超过4K,当cookie超过4KB是,会面临被裁剪的命运

    • 每次请求都会携带在http头中,过量的cookie会损耗性能

    • cookie会紧跟域名,同一个域名下的所有请求都会携带cookie

    • 不安全,服务器没法分辨用户和攻击者,攻击者可以读取网络上其他用户信息,包含HTTP Cookie的所有内容,以便进行中间攻击,使用跨站点脚本技术可以窃取cookie

    Web Storage

    localStorage

    localStorage是持久化的本地存储,存储在其中的数据永远不会过期,只能手动删除,遵循同源策略

    sessionStorage

    sessionStorage是临时性的本地存储,会话级别,当页面或者会话结束时,存储内容也随之被释放,遵循同源策略,但是要保证在同一个窗口,否则无法共享内容

      // localStorage
      保存数据:localStorage.setItem(key, value)
      读取数据:localStorage.getItem(key)
      移除数据:localStorage.removeItem(key)
      清除所有数据:localStorage.clear()
      得到某个索引的key:localStorage.key(index)
    
      // sessionStorage
      保存数据:sessionStorage.setItem(key, value)
      读取数据:sessionStorage.getItem(key)
      移除数据:sessionStorage.removeItem(key)
      清除所有数据:sessionStorage.clear()
      得到某个索引的key:sessionStorage.key(index)
    

    web storage 存储容量大,根据浏览器的不同,存储容量乐意达到5~10M之间 chrome,Firefox,edge都是5M,而且仅位于浏览器端,不与服务端发生通信

    indexedDB

    indexedDB是一个运行在浏览器上的非关系型数据库,一般来说是没有存储上限的,不仅可以存储字符串,还可以存储二进制数据

    indexedDB 允许存入大量数据,提供查找接口,还能建立索引,就数据库类型而言,indexedDB 不属于关系型数据库(不支持sql查询语句),更接近NoSQL数据

    特点

    • 键值对储存, indexedDB内部采用对象仓库(object store)存放数据

    • 异步,indexedDb操作时不会锁死浏览器,用户依然可以进行其他操作

    • 支持事务,只要有一步失败,整个事务就都取消,数据库回滚到事务发生之前的状态,不存在之改写一部分数据的情况

    • 同源限制,每一个数据库对应创建他的域名,网页只能访问自身域名下的数据库,而不能访问跨域的数据库

    • 存储空间大

    • 支持二进制存储

    操作

      // 建立打开 indexedDB
    
      window.indexedDB.open('testDB')
    
      // 关闭indexedDB 
    
      indexdb.close()
    
      // 删除indexedDB
       
       indexedDB.deleteDatabase(indexdb)
    

    基本概念

    indexedDB是一个比较复杂的API,涉及不少概念,它把不同的实体,抽象成一个个对象接口

    • 数据库 数据库是一系列相关的容器,每个域名(协议+端口+域名)都可以新建任意多个数据库, 同时indexedDB数据库有版本的概念,同一时刻只能有一个版本的数据库存在,如果要修改数据库结构,只能通过升级数据库版本完成

    • 对象仓库 每个数据库包含若干个对象仓库, 类似于关系型数据库的表格

    • 数据记录 对象仓库保存的数据记录,每个记录类似于关系型数据库的行,但是只有逐渐和数据体两部分,主键用来建立默认索引,必须是不同的

    • 索引 为了加速数据的检索,可以在对象仓库里面,为不同的属性建立索引

    • 事务 数据记录的读写和删改都要通过事务完成。事务对象提供error,aboutcomplete三个事件,用来监听操作结果

    操作流程

    • 打开数据库

        // 打开数据库
        var request = window.indexedDB.open(databaseName, version)
        // 改方法接受两个参数,第一个参数是字符串,表示数据库的名字,如果指定的数据不存在,就会创建新的数据库,第二个是整数,表示数据库版本,如果省略,
        // indexedDB.open()返回一个IDBRequest对象。这个对象通过三个事件error,success,upgradeneeded 处理数据库的操作结果
        // error 事件表示打开数据库失败
        request.onerror = function(event) {
          console.log('数据库打开失败')
        }
        // success 事件表示成功打开的数据
        var db
        request.onsuccess = function(event) {
          db.request.result
          console.log('数据库打开成功')
        } 
        // success 事件表示成功打开的数据 此时通过request对象的result属性拿到数据库对象
        var db
        request.onsuccess = function(event) {
          db.request.result
          console.log('数据库打开成功')
        } 
        // upgradeneeded 事件如果指定的版本号大于数据的实际版本号,就会发生数据库升级事件 此时通过request对象的result属性拿到数据库对象
        var db;
        request.onupgradeneeded = function (event) {
          db = event.target.result;
        }
      
    • 新建数据库

      新建数据库和打开数据库是同一个操作,如果指定的数据库不存在就会创建,后续的操作主要是在upgradeneeded事件的监听函数里面完成,因为这时版本从无到有,所以会触发这个事件

      通常新建数据库之后,第一件事是新建对象仓库(即新建表)

        request.onupgradeneeded = function(event) {
          db = event.target.result
          var objectStore = db.createObjectStore('person', {keyPath: 'id'})
        }
      

      上述代码,数据库新建成功之后,新增一张叫做person的表格,主键是id

      更好的写法是先判断一下这张表格是否存在,如果不存在再新建

        request.onupgradeneeded = function (event) {
          db = event.target.result
          var objectStore;
          if(!db.objectStoreNames.contains('person')) {
            objectStore = db.createObjectStore('person', {keyPath: 'id'})
          }
        }
      

      如果数据记录里面没有适合主键的属性,那么可以让indexedDB自动生成主键

        var objectStore = db.createObjectStore('person', {autoIncrement: true})
      

      新建对象仓库之后,可以新建索引

        request.onupgradeneeded = function(event) {
          db = event.target.result
          var objectStore = db.createObejctStore('person', {keyPath: 'id'})
          objectStore.createIndex('name', 'name', {unique: false})
          objectStore.createIndex('email', 'email', {unique: false})
        }
      
    • 新增数据

      新增数据指的是向对象仓库写入数据记录,这需要通过事务完成

        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()方法,向表格写入一条数据

      写入是一个异步操作,通过监听连接对象的success事件和error事件,了解事件是否写入成功

    • 读取数据

      读取数据也是通过事务完成

        function read() {
          var transaction = db.transaction(['person'])
          var objectStore = transaction.objectStore('person')
          // objectStore.get(1) 参数是主键的值
          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('没有获取到数据')
            }
          ]
        }
      
    • 遍历数据

      遍历数据表格的所有记录,要使用指针对象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)
              cusor.continue()
            } else {
              console.log('没有更多数据了!')
            }
          }
        }
        readAll()
      

      上述代码中,新建指针对象的openCursor()方法是一个异步操作,所以要监听success时间

    • 更新数据

      更新数据用IDBObject.put()方法

        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()
      
    • 删除数据

      IDBOjectStore.delete()方法用于删除记录

        function remove() {
          var request = db.transaction(['person'], 'readwrite')
            .objectStore('person')
            .delete(1)
          request.onsuccess = function (event) {
            console.log('数据删除成功');
          }
        }
        remove()
      
    • 使用索引 索引的意义在于,可以让你搜索任意字段,也就是说从任意字段拿到数据记录。如果不建立索引,默认只能搜索主键(即从主键取值)

        objectStore.createIndex('name', 'name', { unique: false });
      
        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 {
            // ...
          }
        }
      

      myself understand

      • 使用 window.indexedDB.open(databaseName, version) 创建数据库的时候如果数据库不存在,会触发 onupgradeneeded 方法

      • 如果 创建数据库的时候数据库已存在, 会触发 onsuccess方法

      • 在实际应用中,我们应该先触发一次onupgradeneeded来创建数据库和我们所需要的表

      • 然后在onsuccess方法中实现自己想要实现的方法

      • 表格的增删一般在数据库版本变更的时候操作 即在onupgradeneeded方法中

      • 数据的增删查等操作一般在onsuccess方法中实现,此时不能涉及到数据库版本变更,否则会报错


    起源地下载网 » 浏览器存储方式学习 cookie, session, localstorage, indexedDB

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元