在不填满磁盘的情况下检测 Firefox IndexedDB 或 Web Storage 存储限制?

Detect Firefox IndexedDB or Web Storage storage limit, without filling up the disk?

我想使用 IndexedDB 处理大量数据。太多数据无法放入内存。为此,我想使用 Firefox 的 IndexedDB 持久存储,它允许我存储超过 2GB 的数据 (Firefox apparently has a limit of 2GB imposed on non-persistent storage)。

但是,我 运行 遇到了一个问题。 Firefox 似乎没有对我可以存储在持久存储中的数据量施加限制。事实上,如果我留下下面的示例 运行ning,它显然会 运行 直到磁盘已满!

示例(Online)(在Firefox中必须是运行!):

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <title>Firefox IndexedDB Limit Test</title>
    </head>
    <body>
        <script>
(function() {
'use strict';

var IDBReq = indexedDB.open('testdb', {
    version: 1,
    storage: 'persistent'
});

IDBReq.onupgradeneeded = function() {
    this.result.createObjectStore('data');
};

var logmsg;
IDBReq.onsuccess = function() {
    var DB = this.result;
    var size = 0;

    var next = function(i) {
        var data = new Uint8Array(0xFFFF);
        crypto.getRandomValues(data);

        size += data.length;
        logmsg = 'size: ' + size + 'b ' + (size / (1024 * 1024 * 1024)) + 'gb';

        var store = DB.transaction(['data'], 'readwrite').objectStore('data');
        var storeReq = store.add(data, 'data-' + i);
        storeReq.onsuccess = function() {
            next(i + 1);
        };
        storeReq.onerror = function() {
            console.log('storeReq error');
            console.log(this.error);
        };
    };
    next(1);
};
setInterval(function() {
    if (logmsg) {
        console.log(logmsg);
        logmsg = null;
    }
}, 1000);

})();
        </script>
    </body>
</html>

出于显而易见的原因,填满用户的驱动器并不理想。如果用户没有足够的可用磁盘 space,最好根本不要尝试 运行,或者至少在超过 X% 已满时停止。

奇怪的是,according to MDN,浏览器似乎应该对存储的数据量施加限制:

The maximum browser storage space is dynamic — it is based on your hard drive size. The global limit is calculated as 50% of free disk space. In Firefox, an internal browser tool called the Quota Manager keeps track of how much disk space each origin is using up, and deletes data if necessary.

So if your hard drive is 500GB, then the total storage for a browser is 250GB. If this is exceeded, a process called origin eviction comes into play, deleting entire origin's worth of data until the storage amount goes under the limit again. There is no trimming effect put in place, to delete parts of origins — deleting one database of an origin could cause problems with inconsistency.

There's also another limit called group limit — this is defined as 20% of the global limit. Each origin is part of a group (group of origins). There's one group for each eTLD+1 domain.

但是,我的测试在驱动器填满时从未抛出任何错误。

现在我的问题是,有什么方法可以确保将大量数据放入 Firefox 的 IndexedDB 持久存储中,不会填满用户的驱动器,让他们非常非常生气?

注意 MDN 文章中的行:

Temporary data storage does not elicit any user prompts, but there are Storage limits.

它可能更清楚,但这意味着存储限制仅适用于临时存储。因此,全局限制和组限制对持久存储无效。

您可以考虑切换到临时存储。但是,如果您需要持久性,那么在 Firefox 实施 navigator.storageQuota or navigator.storageManager 之前,您可能就不走运了,以哪个为准。