indexedDB 存储 js文件 xml文件 大文件缓存 并导出使用

目录

一. 打开数据库

二. 在数据库中创建一个对象仓库

(1). 更新

(2). 成功

(3). 错误

(4). 被阻断

三 .获得文件数据并存储和提取使用

(1) . 获取文件

(2).存储到数据库

(3).读取文件


起因:在网速慢,需要加载的文件很大(大于5M),每次刷新界面都要重新加载的情况。选择把文件存在浏览器的indexedDB数据库中,在存储后,以后再刷新界面,从本地的数据库中提取,就不用每次加载了。

(如果是打开本地的文件,上传到数据库,网上有很多成熟的方案)

参考文献:http://www.ruanyifeng.com/blog/2018/07/indexeddb.html

                  https://developer.mozilla.org/zh-CN/docs/Web/API/IndexedDB_API

                  https://developer.mozilla.org/zh-CN/docs/Web/API/IndexedDB_API/Using_IndexedDB

                  读取文件:https://developer.mozilla.org/zh-CN/docs/Web/API/FileReader

目标在数据库存入2个文件 一个是js文件,主键就是js ; 另一个是个xml文件,主键就是xml

一. 打开数据库

先定义变量

var indexedDB = window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB || window.OIndexedDB || window.msIndexedDB;

var request = indexedDB.open("opencv",1);

var db;

open这个动作,如果以前没有这个数据库,就会新建数据库,

                          如果有数据库,就打开,

                          如果有数据库,但版本改变,就会执行升级,                         

open接受2个参数,数据库名 和 版本号,版本号可以不写,不写的话,第一次版本默认是1

二. 在数据库中创建一个对象仓库

 打开数据库就像任何其他操作一样 — 你必须进行 "request"。

open 请求不会立即打开数据库或者开始一个事务。 对 open() 函数的调用会返回一个我们可以作为事件来处理的包含 result(成功的话)或者错误值的 IDBOpenDBRequest 对象。在 IndexedDB 中的大部分异步方法做的都是同样的事情 - 返回一个包含 result 或错误的 IDBRequest 对象。open 函数的结果是一个 IDBDatabase 对象的实例。

返回结果有4中情况 onupgradeneeded(更新)、onsuccess(成功)、onerror(失败)、onblocked(被阻塞)

(1). 更新

     在第一次新建数据库时,版本不写会默认是1,版本从无到有,也算是版本更新。

    当版本改变,也会触发更新。

    在第一次新建数据库后,第一个步骤是新建表,如果是再次更新时,就要判断数据库中有没有这个表,如果没有就新建表。

    ① 新建表 'oc'

    ② 如果是再次更新,表存在,就删除表中的数据。

    删除数据的方法delete()

    request.onupgradeneeded = function (event) {
    console.log('数据库更新');
    db = event.target.result;
    var objectStore;
    if (!db.objectStoreNames.contains('oc')) {
      console.log("新建表");
      objectStore = db.createObjectStore('oc');    
    }else{
      console.log("版本更新,数据删除更新");
      var t = event.target.transaction;
      var requ = t.objectStore('oc').delete("js");
      var requ2 = t.objectStore('oc').delete("xml");
      requ.onsuccess = function (event) { console.log('数据库表数据js删除成功'); };
      requ.onerror = function (event) { console.log('数据库表数据js删除成功'); };
      requ2.onsuccess = function (event) { console.log('数据库表数据xml删除成功'); };
      requ2.onerror = function (event) { console.log('数据库表数据xml删除成功'); };
    }      
}

(2). 成功

在新建数据库时,先执行更新,再执行成功。

在数据库存在时,版本号不变的情况下,直接执行成功。

检查表里是否有js文件数据存在,如果存在,就加载把2个文件读取出来 read()

                                                    如果不存在,就获取2个文件getFile(),并存到数据库中。

                                                    如果检测失败,也获取这2个文件,因为主键是一样的,会覆盖之前存的这2个文件。

读取数据的方法get()

这里不严谨的是,如果当用户在存储数据时,把网页关闭了,导致2个文件只有一个存储成功了,

(这里xml是小文件,js是大文件),这时,检测时,如果没检测到js文件,就会把2个文件再加载一遍,

如果不想这样,可以,两个文件分别判断是否存在,分别加载。

(我直接把获取2个文件写在一个函数中了,你可以通过传参,分别获取)

request.onsuccess = function (event) {
    console.log('数据库打开成功');
    db = request.result;      
    db.onerror = function (event) { console.log("Error creating/accessing IndexedDB database"); };
    //是否有表,表里是否有那条数据
    var r = db.transaction(['oc']).objectStore('oc').get('js');
    r.onsuccess = function(event) {
          var d = event.target.result;
       if(!d){ 
          console.log('表中无数据,或数据已清空');
          getFile(); 
       }
       else{
           console.log('加载本地保存数据');
           read('xml');
           read('js');
       } 
    };
    r.οnerrοr= function() {
        console.log('查询失败');
        getFile();
    }    
};

(3). 错误

在数据库打开失败时,可以页面提示打开失败,或者在控制台打印。

request.onerror = function (event) { console.log('数据库打开报错'); };

(4). 被阻断

打印错误信息

request.onblocked = function() { console.log("Your database version can't be upgraded because the app is open somewhere else.");}

三 .获得文件数据并存储和提取使用

(1) . 获取文件

js文件用blob类型存储。

xml文件用arraybuffer类型存储。

当文件加载成功,将文件存到数据库中 putInDB( 类型,主键

function getFile(){
    var xhr = new XMLHttpRequest();
    var xhr2 = new XMLHttpRequest();
    var blob,arraybuffer;
    xhr.open("GET", 根目录+'/static/oc/oc.js', true);
    xhr2.open("GET", 根目录+'/static/oc/hd.xml', true);
    xhr.responseType = "blob";
    xhr2.responseType = "arraybuffer";
    xhr.addEventListener("load", function () {
         if (xhr.status === 200) {          
             blob = xhr.response;              
             console.log('获取opencv.js成功');
              putInDB(blob,'js');                                 
         }
     }, false);
     xhr2.addEventListener("load", function () {
          if (xhr2.status === 200) {
             console.log('获取xml成功');
             arraybuffer = xhr2.response;
             putInDB(arraybuffer,'xml'); 
          }
     }, false);     
    xhr.send();              
    xhr2.send();    
}

(2).存储到数据库

这里用到的数据库的事务,事务提供了三种模式:readonlyreadwrite 和 versionchange 。

想要执行写这个操作,用readwrite。

增加一条数据时,add() 方法的调用时,对象仓库中不能存在相同键的对象。

如果新加的这条数据,可以覆盖数据库中本来存在相同键的,用put()方法。

写入完,读取数据,加载使用 read()

function putInDB(type,id) {
   var transaction = db.transaction(["oc"], 'readwrite');
   var put = transaction.objectStore('oc').put(type,id);
   put.onsuccess = function (event) { console.log('数据'+id+'写入成功'); };
   put.onerror = function (event) { console.log('数据'+id+'写入失败'); }
   read(id);
}

(3).读取文件

如果是使用js,可以在html或jsp页面内写一个带id的script,用于写入。

  (想过写入到某个空的js文件中,再在某个想执行的时候执行,

    但浏览器不能让这样做的,如果有更好的写入执行,请留个言指教下 ^-^)

这里对读取出的不同数据做处理

比如读取js文件,用 FileReader.readAsText()方法将数据转变成字符串。

转变完成,写入到script中,用jquery的html()方法写入,就直接执行了。

html: <script type="text/javascript" id="oc"></script>

js:

var xmlreq;
function read(id) {
   var req = db.transaction(['oc']).objectStore('oc').get(id);    
   req.onerror = function(event) { console.log('读取'+id+'数据失败'); };
   req.onsuccess = function(event) {
       if(id=='xml'){
           xmlreq = event.target.result;

           let data = new Uint8Array(xmlreq);

           // 这里可以处理xml文件数据
       }else{
          var file = event.target.result;
          var reader = new FileReader();
          reader.addEventListener("loadend", function() { 
                //处理数据 
                $("#oc").html(reader.result);              
          });
          reader.readAsText(file);
       }
   };
}

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值