使用Javascript在客户端上存储超过5mb

时间:2013-09-25 09:14:26

标签: javascript html5 local-storage indexeddb web-sql

我想在客户端浏览器中存储超过5mb。浏览器可以是Firefox,Chrome,Internet Explorer,Safari(iOS)或Windows Phone 8浏览器。我的第一个想法是关于localStorage,因为它已经在上述浏览器中实现。

作为奖励功能,应该可以在特殊浏览器上节省超过5mb。因此,我首先检查浏览器引擎,然后选择最佳保存方法。我只需要存储键 - 值对。

如果我尝试下面的代码,我在Chrome上写下它永远或极端迟到。 iPhone工作(webSQL)除了iOS 7.在iOS 7中是一个已知的浏览器错误,它会导致数据库崩溃。我希望他们能尽快解决这个问题: - )

这可以实现吗?以下是我的第一个想法:

<!DOCTYPE html>

<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=Edge">
    <title>Datenbank Test</title>

    <script type="text/javascript">

        alert(navigator.userAgent.toLowerCase());

        var db = {};
        db.debug = true;
        db.__browser = navigator.userAgent.toLowerCase();
        db.__database = 'fDB';
        db.__driver = undefined;

        db.initialize = function () {
            if (db.__browser.search(/(chrome|firefox|msie)/) > -1) {
                db.__driver = 'indexedDB';
                db.indexedDB.initialize();
            }
            else if (db.__browser.search(/(iphone|safari)/) > -1) {
                db.__driver = 'webSQL';
                db.webSQL.initialize();
            }
            else {
                db.__driver = 'localStorage';
            }

        };

        db.setItem = function (iKey, iVal) {
            switch (db.__driver) {
                case 'indexedDB':
                    db.indexedDB.setItem(iKey, iVal);
                    break;
                case 'webSQL':
                    db.webSQL.setItem(iKey, iVal);
                    break;
                case 'localStorage':
                    localStorage.setItem(iKey, iVal);
                    break;
                default:
                    if (db.debug) {
                        console.log('An error occured.');
                    }
            }
        }

        db.getItem = function (iKey, callback) {
            switch (db.__driver) {
                case 'indexedDB':
                    db.indexedDB.getItem(iKey, function (data) {
                        callback(data);
                    });
                    break;
                case 'webSQL':
                    db.webSQL.getItem(iKey, function (data) {
                        callback(data);
                    });
                    break;
                case 'localStorage':
                    callback(localStorage.getItem(iKey));
                    break;
                default:
                    if (db.debug) {
                        console.log('An error occured.');
                    }
            }
        };

        db.setItemsBulk = function (items) {
            switch (db.__driver) {
                case 'indexedDB':
                    db.indexedDB.setItemsBulk(items);
                    break;
                case 'webSQL':
                    db.webSQL.setItemsBulk(items);
                    break;
                case 'localStorage':
                    alert('Not implemented yet. sorry :-(');
                    break;
                default:
                    if (db.debug) {
                        console.log('An error occured.');
                    }
            }
        };

        db.count = function (callback) {
            switch (db.__driver) {
                case 'indexedDB':
                    db.indexedDB.count(function (data) {
                        callback(data)
                    });
                    break;
                case 'webSQL':
                    // TODO
                    break;
                case 'localStorage':
                    callback(localStorage.length);
                    break;
                default:
                    if (db.debug) {
                        console.log('An error occured.');
                    }
            }
        };

        db.indexedDB = {};
        db.indexedDB.__dbHandler = undefined;
        db.indexedDB.__request = undefined;

        db.indexedDB.initialize = function () {
            window.indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
            window.IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction || window.msIDBTransaction;
            window.IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange || window.msIDBKeyRange;

            db.indexedDB.__request = window.indexedDB.open(db.__database, 1337);
            db.indexedDB.__request.onsuccess = function (e) {
                console.log('IndexedDB opened');
                db.indexedDB.__dbHandler = e.target.result;
            };
            db.indexedDB.__request.onupgradeneeded = function (e) {
                console.log('IndexedDB upgradeNeeded');
                db.indexedDB.__dbHandler = e.target.result;
                if (db.indexedDB.__dbHandler.objectStoreNames.contains('data')) {
                    db.indexedDB.__dbHandler.deleteObjectStore('data');
                }
                var objectStore = db.indexedDB.__dbHandler.createObjectStore('data', { keyPath: "iKey" });
                objectStore.createIndex('iKey', 'iKey', { unique: true });
            };
        };

        db.indexedDB.setItem = function (iKey, iVal) {
            var trans = db.indexedDB.__dbHandler.transaction(['data'], "readwrite");
            var store = trans.objectStore("data");
            var request = store.put({ iKey: iKey, iVal: iVal });
        };

        // Use the callback to get the values
        db.indexedDB.getItem = function (iKey, callback) {
            try {
                var trans = db.indexedDB.__dbHandler.transaction(['data'], "readwrite");
                var store = trans.objectStore("data");
                var request = store.get(iKey);
                request.onsuccess = function (e) {
                    callback(request.result != null && request.result.iVal != null ? request.result.iVal : null);
                };
                request.onerror = function (e) {
                    if (db.debug)
                        console.log(e);
                };
            } catch (e) {
                alert(e);
            }

        };

        db.indexedDB.setItemsBulk = function (items) {
            if (!items.length) {
                return;
            }
            var trans = db.indexedDB.__dbHandler.transaction(["data"], "readwrite");
            var store = trans.objectStore("data");
            var request = store.put(items[0]);
            request.onsuccess = function onSuccessHandler() {
                items = items.splice(1);
                if (!items.length) {
                    return;
                }
                request = store.put(items[0]);
                request.onsuccess = onSuccessHandler;
            };
        };

        db.indexedDB.count = function (callback) {
            var trans = db.indexedDB.__dbHandler.transaction(["data"], "readwrite");
            var store = trans.objectStore("data");
            var keyRange = IDBKeyRange.lowerBound(0);
            var cursorRequest = store.openCursor(keyRange);
            var count = 0;
            cursorRequest.onsuccess = function (e) {
                var result = e.target.result;
                result ? ++count && result.continue() : callback(count);
            };

        };

        db.webSQL = {};
        db.webSQL.__dbHandler = undefined;

        db.webSQL.initialize = function () {
            db.webSQL.__dbHandler = openDatabase('fDB', '1.0', 'place for comment', 50 * 1024 * 1024);
            db.webSQL.__dbHandler.transaction(function (tx) {
                tx.executeSql('CREATE TABLE IF NOT EXISTS data (iKey unique, iVal VARCHAR(255))');
            });
        }

        db.webSQL.setItem = function (iKey, iVal) {
            db.webSQL.__dbHandler.transaction(function (tx) {
                tx.executeSql('INSERT OR REPLACE INTO data (iKey, iVal) VALUES (?, ?)', [iKey, iVal]);
            });
        };

        db.webSQL.getItem = function (iKey, callback) {
            try {
                db.webSQL.__dbHandler.transaction(function (tx) {
                    tx.executeSql('SELECT iVal FROM data WHERE iKey = ?', [iKey], function (tx, results) {
                        //console.log(results.rows.item(0).iVal);
                        callback(results.rows.item(0).iVal);
                    });
                });
            }
            catch (e) {
                alert('ERROR: ' + e);
            }
        };

        db.webSQL.setItemsBulk = function (items) {
            db.webSQL.__dbHandler.transaction(function (tx) {
                for (var i = 0; i < items.length; i++) {
                    tx.executeSql('INSERT OR REPLACE INTO [data] (iKey, iVal) VALUES (?, ?)', [items[i].iKey , items[i].iVal]);
                }
            });
        }

        db.webSQL.count = function (callback) {
            db.webSQL.__dbHandler.transaction(function (tx) {
                tx.executeSql('SELECT COUNT(*) AS c FROM data', [], function (tx, data) {
                    callback(data.rows.item(0).c);
                });
            });
        };

        function bigData() {
            var items = [];
            for (var i = 1; i < 40000; i++) {
                items.push({ iKey: i, iVal: "Now this is the story all about how My life got flipped turned upside down. And Id like to take a minute just sit right there Ill tell you how I became the prince of a town called Bel Air" });
            }
            console.log(items);
            db.setItemsBulk(items);
        }

        db.initialize();
    </script>



</head>
<body>
    Dies ist ein Datenbank-Test
    <button onclick="db.setItem('browser', navigator.userAgent);">AddItem</button>
    <button onclick="db.getItem('browser', function(e) {alert(e);});">GetItem</button>
    <button onclick="db.count(function (e) { alert(e); });">Gebe Count aus.</button>

    <button onclick="bigData();">Insert BIG DATA</button>
    <button onclick="db.getItem(50, function (d) { document.getElementById('entry').innerHTML = 'Eintrag 50: ' + d; });">Load Sample Entry</button>

    <button onclick="db.__driver = 'localStorage';">driver = localStorage</button>
    <button onclick="db.__driver = 'webSQL';">driver = WebSQL</button>
    <button onclick="db.__driver = 'indexedDB';">driver = indexedDB</button>

    <div id="driver"></div>
    <div id="entry"></div>

    <script type="text/javascript">
        document.getElementById('driver').innerHTML = 'Datenbank: ' + db.__driver;

    </script>
</body>
</html>

2 个答案:

答案 0 :(得分:0)

我现在使用localForage。它对我很有用。它会自动选择在用户浏览器中保存数据的最佳方法。

见这里:https://github.com/mozilla/localForage

答案 1 :(得分:0)

看起来非常好的实现 - 在大多数情况下简洁且可用。

您可以选中window.indexedDBwindow.openDatabase,而不是检查userAgent。

在indexeddb实现中,索引主键不是必需的,因为它已经编入索引。对于整个记录的计数,不需要关键范围。