HTML5 IndexDB 用户本地化存储离线数据库的使用

HTML5 IndexDB 用户本地化存储离线数据库的使用

了解的朋友,知道Web SQL曾是HTML5 离线数据存储的一种解决方案,它是一个基于SQLite 的离线数据库。但W3C 的 WebDatabase 规范最终选择主推IndexDB,对Web SQL则不再提供维护。

IndexDB是一个NoSQL类型的数据库,可在客户端进行大量结构化数据存储,能使用索引高效率搜索数据进行读写和管理操作。而且它的大多操作都是在异步模式下执行,能够让你使用高效的JavaScript事件驱动模块,减少等待,操作更加流畅。它也有为同步模式提供的API,但在碧海情天整理资料的时候据说还没有实现。

IndexedDB概述

1. IndexedDB存储形式为键值对:它可以存储一些复杂的对象,而键可以存储这些对象的属性值,并且可以使用索引对对象的属性进行快速检索。
2. IndexedDB建立在交互数据库模型的基础上:任何对IndexedDB的操作都发生一个交互操作(transaction,事务),如它提供的索引、表、游标等均与一个transaction关联,它定义了交互的生存时间与结束时抛出的事件,这样能很好的处理web程序在不同的tab窗口中实例的互操作。
3. IndexedDB的API大多是异步的:你可以向数据库发出操作的“请求”,当操作完成时会产生一个DOM事件,通过事件的类型会知道操作是否成功。
4. IndexedDB使用“请求”机制:操作对象会接收到DOM的success和failure事件,它也有相应的onsuccess和onerror的属性;对象还有readyState、result和errorCode属性来查看当前“请求”的状态,而result属性则根据不同的“请求”返回不同的结果。
5. IndexedDB 使用DOM事件机制来处理“请求”的结果:DOM事件的type属性提示操作是否成功,target属性指向发生“请求”的对象(大多数情况下是IDBRequest对象)。
6. IndexedDB工作基本流程:
    1. 创建一个交互操作对象
    2. 发送操作“请求”
    3. 通过监听DOM事件等待操作完成
    4. 处理“请求”结果

IndexedDB具体使用方法

1. 初始化声明
var dbName = "赵亮"; //数据库名称
var dbVersion = 2.0; //数据库版本
var tablename = "碧海情天"; //表名
2. 初始并实例化IndexDB数据上下文
//定义一个IndexDB方法集合对象
var H5AppDB = {};
//实例化IndexDB数据上下文,这边根据浏览器类型来做选择
var indexedDB = window.indexedDB || window.webkitIndexedDB ||window.mozIndexedDB;
if ('webkitIndexedDB' in window) {
    window.IDBTransaction = window.webkitIDBTransaction;
    window.IDBKeyRange = window.webkitIDBKeyRange;
}
H5AppDB.indexedDB = {};
H5AppDB.indexedDB.db = null;
//错误信息,打印日志
H5AppDB.indexedDB.onerror = function (e) {
    log.debug(e);
};
3. 打开数据库,初始化数据库,并创建存储对象
当创建数据库之后,需要添加数据,IndexedDB采用对象存储。首先要检查数据库的版本,若不是所期望的值,就要调用setVerion()方法来设置它的版本。
H5AppDB.indexedDB.open = function() {
    //初始IndexDB
    var request = indexedDB.open(dbName, dbVersion);
    request.onsuccess = function(e) {
        // Old api: var v = "2-beta"; 
        log.debug("成功打开数据库: " + dbName);
        H5AppDB.indexedDB.db = e.target.result;
        var db = H5AppDB.indexedDB.db;
        if (db.setVersion) {
            console.log("旧版本号: " + db.setVersion);
            if (db.version != dbVersion) {
                var req = db.setVersion(dbVersion);
                req.onsuccess = function() {
                    if (db.objectStoreNames.contains(tablename)) {
                        db.deleteObjectStore(tablename);
                    }
                    var store = db.createObjectStore(tablename, {
                        keyPath: "timeStamp"
                    }); //keyPath:主键,唯一性
                    var trans = req.result;
                    trans.oncomplete = function(e) {
                        console.log("== 传输完成 ==");
                        H5AppDB.indexedDB.getAllTodoItems();
                    }
                };
            } else {
                H5AppDB.indexedDB.getAllTodoItems();
            }
        } else {
            H5AppDB.indexedDB.getAllTodoItems();
        }
    }
    // 如果版本不一致,执行版本升级的操作
    request.onupgradeneeded = function(e) {
        log.debug("开始升级数据库。");
        H5AppDB.indexedDB.db = e.target.result;
        var db = H5AppDB.indexedDB.db;
        if (db.objectStoreNames.contains(tablename)) {
            db.deleteObjectStore(tablename);
        }
        var store = db.createObjectStore(tablename, {
            keyPath: "timeStamp"
        }); //NoSQL类型数据库中必须的主键,唯一性
        H5AppDB.indexedDB.getAllTodoItems();
    }
    request.onfailure = H5AppDB.indexedDB.onerror;
};
4. 获取对象信息,并进行轮询读取,然后绑定到页面
H5AppDB.indexedDB.getAllTodoItems = function() {
    var todos = document.getElementById("todoItems");
    todos.innerHTML = "";
    var db = H5AppDB.indexedDB.db;
    var trans = db.transaction([tablename], "readwrite"); //通过事物开启对象
    var store = trans.objectStore(tablename); //获取到对象的值
    // Get everything in the store;
    var keyRange = IDBKeyRange.lowerBound(0);
    var cursorRequest = store.openCursor(keyRange); //开启索引为0的表
    cursorRequest.onsuccess = function(e) {
        var result = e.target.result;
        if ( !! result == false) return;
        renderTodo(result.value);
        result.
        continue (); //这边执行轮询读取
    };
    cursorRequest.onerror = H5AppDB.indexedDB.onerror;
};

//绑定数据
function renderTodo(row) {
    var todos = document.getElementById("todoItems");
    var li = document.createElement("li");
    var a = document.createElement("a");
    var t = document.createTextNode(row.text);

    a.addEventListener("click", function() {
        H5AppDB.indexedDB.deleteTodo(row.timeStamp);
    }, false);

    a.textContent = " [Delete]";
    li.appendChild(t);
    li.appendChild(a);
    todos.appendChild(li);
};
5. 添加数据对象
H5AppDB.indexedDB.addTodo = function(todoText) {
    var db = H5AppDB.indexedDB.db;
    var trans = db.transaction([tablename], "readwrite");
    var store = trans.objectStore(tablename);
    var newArray = new Array("键1", "值1");
    //数据以对象形式保存,体现NoSQL类型数据库的灵活性
    var data = {
        "text": todoText,
        "timeStamp": new Date().getTime(),
        "obj": newArray
    };
    var request = store.put(data); //保存数据
    request.onsuccess = function(e) {
        H5AppDB.indexedDB.getAllTodoItems();
    };

    request.onerror = function(e) {
        log.debug("添加出错: ", e);
    };
};

function addTodo() {
    var todo = document.getElementById("todo");
    H5AppDB.indexedDB.addTodo(todo.value);
    todo.value = "";
}
可以随意添加BJson格式的对象,体现NoSQl类型数据库的优越性。

IndexedDB采用最小化的错误事件处理,你不会看到很多类型的错误,它只提供一个错误的事件,可以通过event.target.errorCode来查看错误的信息,通常大多的错误都是用户不允许web操作本地的数据库,远程web所拥有的权限问题。

6. 删除数据对象(根据主键删除)
H5AppDB.indexedDB.deleteTodo = function(id) {
    var db = H5AppDB.indexedDB.db;
    var trans = db.transaction([tablename], "readwrite");
    var store = trans.objectStore(tablename);
    var request = store.delete(id);//根据主键来删除
    request.onsuccess = function(e) {
        H5AppDB.indexedDB.getAllTodoItems();
        alert("删除成功");
    };
    request.onerror = function(e) {
        log.debug("删除出错: ", e);
    };
};

IndexedDB的安全性限制

IndexedDB 使用同源原则,这意味着它把存储空间绑定到了创建它的站点的源(典型情况下,就是站点的域或是子域),所以它不能被任何其他源访问。

要着重指出的一点是,IndexedDB 不适用于从另一个站点加载进框架的内容 (不管是用 frame 还是 iframe)。

发布了33 篇原创文章 · 获赞 3 · 访问量 31万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览