1

クライアントブラウザに5MB以上保存したいです。ブラウザは、Firefox、Chrome、Internet Explorer、Safari (iOS)、または Windows Phone 8 ブラウザです。私が最初に考えたのは、前述のブラウザーに既に実装されている localStorage についてでした。

おまけ機能として、特別なブラウザで 5MB 以上節約できるはずです。したがって、まずブラウザ エンジンをチェックしてから、最適な保存方法を選択します。キーと値のペアのみを保存する必要があります。

以下のコードを試してみると、クロムで書いたことがないか、極端に遅くなりました。iPhone は iOS 7 以外で動作します (webSQL)。iOS 7 では、DB をクラッシュさせる既知のブラウザーのバグがあります。彼らがすぐにそれを修正することを願っています:-)

これを実装することは可能ですか?以下は私の最初のアイデアです:

<!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>
4

2 に答える 2

0

私は今localForageを使用しています。それは私にとって非常にうまく機能します。ユーザーのブラウザにデータを保存するための最適な方法が自動的に選択されます。

こちらをご覧ください: https://github.com/mozilla/localForage

于 2014-04-02T20:17:50.167 に答える
0

非常に優れた実装のように見えます-簡潔でほとんどの場合に使用できます。

userAgent をチェックする代わりに、window.indexedDBまたはをチェックすることができますwindow.openDatabase

indexeddb の実装では、すでにインデックスが作成されているため、主キーのインデックス作成は必要ありません。レコード全体をカウントする場合、キー範囲は必要ありません。

于 2014-04-03T04:36:30.003 に答える