【问题标题】:What is the max size of localStorage values?localStorage 值的最大大小是多少?
【发布时间】:2011-02-28 16:15:56
【问题描述】:

由于localStorage(当前)仅支持字符串作为值,并且为了做到这一点,对象需要在存储之前被字符串化(存储为 JSON 字符串),是否有关于长度的定义限制值。

有谁知道是否有适用于所有浏览器的定义?

【问题讨论】:

标签: javascript html local-storage


【解决方案1】:

引用Wikipedia article on Web Storage:

Web 存储可以简单地视为对 cookie 的改进,提供更大的存储容量(Google Chrome(https://plus.google.com/u/0/+FrancoisBeaufort/posts/S5Q9HqDB8bh)、Mozilla Firefox 和 Opera 中每个源 10 MB;Internet 中每个存储区域 10 MB Explorer)和更好的编程界面。

同时引用John Resig article [2007 年 1 月发布]:

存储空间

暗示,使用 DOM 存储, 你有更多的存储空间 空间比典型的用户代理 对 Cookie 施加的限制。 但是,提供的金额 在规范中没有定义, 也不是有意义的广播 用户代理。

如果您查看 Mozilla 源代码 我们可以看到5120KB是默认的 整个域的存储大小。 这为您提供了更多的空间 使用比典型的 2KB 饼干。

但是,这个存储区的大小 可以由用户自定义(所以 不保证5MB存储区域, 也不是暗示)和用户代理 (例如,Opera 可能只提供 3MB - 但只有时间会证明一切。)

【讨论】:

  • @Cupidvogel 不,这意味着每个 domain (origin) 可以在任何单个客户端上存储 5MB。数据存储在客户端机器上 - localStorage 机制绝不会跨客户端交互。
  • 不,我只是想确保同一域的多个页面可以访问相同的数据。我经常发现短语 domain 和 page 拼写成同义词,所以只是想确定一下!
  • 但是,single 值是否存在限制? (如果我有很多标志要存储,将其作为 JSON 存储在单个属性中有多安全?)
  • 我有 5MB 的 Safari 和 10MB 的 Chrome 39(不确定它是什么时候从 5MB 提升的)请参阅这篇文章 html5rocks.com/en/tutorials/offline/quota-research
  • @Cupidvogel: 不,不是按域不是,而是按origin,因为该术语用于同源策略等等:方案+主机+端口。 http://example.comhttps://example.com 不是同一个来源(不同的方案)。 http://example.comhttp://www.example.com 不是同一个来源(不同的主机)。 http://example.comhttp://example.com:8080 不是同一个来源(不同的端口)。 HTH。 :-)
【解决方案2】:

实际上 Opera 没有 5MB 的限制。当应用程序需要更多时,它会增加限制。用户甚至可以为域选择“无限存储”。

您可以轻松地test localStorage limits/quota自己。

【讨论】:

  • Chrome 不再崩溃...有趣的一点:5MB 等于 Chrome 上的 250 万个字符。显然,UFT16 用于 localStore。
  • @FelixAlcala 不幸的是,它在 Mac OS X 上崩溃了 Chrome 15.0.874.54 beta。我在 1.500.000 字符时崩溃了。
  • 它在我的设备上崩溃了 chrome,还重置了背景,不过并不奇怪,我的手机内存这么小,它无法处理在 chrome 打开时打开一个愚蠢的手电筒应用程序。
  • @FelixAlcala -- 实际上,JavaScript 公开了UCS-2。虽然它类似于UFT16,但有一些非常重要的区别......主要围绕 UCS-2 早于 UFT 的事实。
  • 我最近在 Chrome 80 上运行了这个测试,得到了 520 万个字符,5MB 仍然允许
【解决方案3】:

这是一个用于找出限制的简单脚本:

if (localStorage && !localStorage.getItem('size')) {
    var i = 0;
    try {
        // Test up to 10 MB
        for (i = 250; i <= 10000; i += 250) {
            localStorage.setItem('test', new Array((i * 1024) + 1).join('a'));
        }
    } catch (e) {
        localStorage.removeItem('test');
        localStorage.setItem('size', i - 250);            
    }
}

这里是the gistJSFiddleblog post

脚本将测试设置越来越大的文本字符串,直到浏览器抛出异常。此时它会清除测试数据并在 localStorage 中设置一个大小键,以千字节为单位存储大小。

【讨论】:

  • 很酷的解决方案。我找到了this one liner,你觉得呢?
  • @brasofilo 我认为一个班轮假设你有 5MB,然后减去正在使用的数量。
  • 哎呀,中枪了。我在使用您的代码时遇到的问题是无法使用 Correct way to convert size in bytes to KB, MB, GB in Javascript 获得正确的结果...我明天会修改此内容,但如果您可以看一下,不胜感激。
  • 提高了这个答案的性能和质量here
  • 现在是 2020 年,这个答案在 Win10 上的 vanilla Chrome 和 Firefox 上都运行良好,大小为 5000。
【解决方案4】:

找出可以存储在localStorage中的单个字符串的最大长度

这个 sn-p 将找到每个域可以存储在 localStorage 中的字符串的最大长度。

//Clear localStorage
for (var item in localStorage) delete localStorage[item];

window.result = window.result || document.getElementById('result');

result.textContent = 'Test running…';

//Start test
//Defer running so DOM can be updated with "test running" message
setTimeout(function () {

    //Variables
    var low = 0,
        high = 2e9,
        half;

    //Two billion may be a little low as a starting point, so increase if necessary
    while (canStore(high)) high *= 2;


    //Keep refining until low and high are equal
    while (low !== high) {
        half = Math.floor((high - low) / 2 + low);

        //Check if we can't scale down any further
        if (low === half || high === half) {
            console.info(low, high, half);
            //Set low to the maximum possible amount that can be stored 
            low = canStore(high) ? high : low;
            high = low;
            break;
        }


        //Check if the maximum storage is no higher than half
        if (storageMaxBetween(low, half)) {
            high = half;
            //The only other possibility is that it's higher than half but not higher than "high"
        } else {
            low = half + 1;
        }

    }

    //Show the result we found!
    result.innerHTML = 'The maximum length of a string that can be stored in localStorage is <strong>' + low + '</strong> characters.';

    //Functions
    function canStore(strLen) {
        try {
            delete localStorage.foo;
            localStorage.foo = Array(strLen + 1).join('A');
            return true;
        } catch (ex) {
            return false;
        }
    }


    function storageMaxBetween(low, high) {
        return canStore(low) && !canStore(high);
    }

}, 0);
<h1>LocalStorage single value max length test</h1>

<div id='result'>Please enable JavaScript</div>

请注意,字符串的长度在 JavaScript 中是有限的;如果你想查看localStorage不限于单个字符串时可以存储的最大数据量,你can use the code in this answer

编辑:堆栈片段不支持localStorage,所以here is a link to JSFiddle

结果

Chrome (45.0.2454.101): 5242878 个字符
Firefox (40.0.1): 5242883 个字符
Internet Explorer (11.0.9600.18036 ): 16386 122066 122070 个字符

我在 Internet Explorer 中每次运行都会得到不同的结果。

【讨论】:

  • 有趣,但是当我在 Edge 浏览器(在 Win 10 上)运行约 1 分钟后进行测试时,您的简单测试会停止我非常强大的系统。所以我不能将新数据附加到您的结果中))
【解决方案5】:

不要假设 5MB 可用 - localStorage 容量因浏览器而异,其中 2.5MB、5MB 和无限制是最常见的值。 来源:http://dev-test.nemikor.com/web-storage/support-test/

【讨论】:

    【解决方案6】:

    您不希望将大型对象字符串化到单个 localStorage 条目中。那将是非常低效的——每次一些细微的细节变化时,整个事情都必须被解析和重新编码。此外,JSON 不能处理对象结构中的多个交叉引用,并且会删除很多细节,例如构造函数、数组的非数值属性、稀疏条目中的内容等。

    相反,您可以使用Rhaboo。它使用大量 localStorage 条目来存储大型对象,因此您可以快速进行小的更改。恢复的对象是保存对象的更准确的副本,API 非常简单。例如:

    var store = Rhaboo.persistent('Some name');
    store.write('count', store.count ? store.count+1 : 1);
    store.write('somethingfancy', {
      one: ['man', 'went'],
      2: 'mow',
      went: [  2, { mow: ['a', 'meadow' ] }, {}  ]
    });
    store.somethingfancy.went[1].mow.write(1, 'lawn');
    

    顺便说一句,我写的。

    【讨论】:

    • 谢谢马丁。你也可以查看我的“evon”回购。它现在只是一个序列化器,墨水很湿,但它比 rhaboo 更快,并且同样通用。 Rhaboo 将很快转换为内部使用。
    • 有用,但我认为这不能解决“localStorage 的最大大小是多少;”的问题通过说明当该库尝试存储超出大小限制的内容时会发生什么以及如何对其做出反应,可以改进您的答案。
    【解决方案7】:

    我编写了这个简单的代码来测试 localStorage 的大小(以字节为单位)。

    https://github.com/gkucmierz/Test-of-localStorage-limits-quota

    const check = bytes => {
      try {
        localStorage.clear();
        localStorage.setItem('a', '0'.repeat(bytes));
        localStorage.clear();
        return true;
      } catch(e) {
        localStorage.clear();
        return false;
      }
    };
    

    Github 页面:

    https://gkucmierz.github.io/Test-of-localStorage-limits-quota/

    我在桌面 chrome、opera、firefox、brave 和 mobile chrome 上的结果相同,大约为 5Mbytes

    一半的结果是 safari ~2Mbytes

    【讨论】:

    【解决方案8】:

    我已经将二进制测试压缩到我使用的这个函数中:

    function getStorageTotalSize(upperLimit/*in bytes*/) {
        var store = localStorage, testkey = "$_test"; // (NOTE: Test key is part of the storage!!! It should also be an even number of characters)
        var test = function (_size) { try { store.removeItem(testkey); store.setItem(testkey, new Array(_size + 1).join('0')); } catch (_ex) { return false; } return true; }
        var backup = {};
        for (var i = 0, n = store.length; i < n; ++i) backup[store.key(i)] = store.getItem(store.key(i));
        store.clear(); // (you could iterate over the items and backup first then restore later)
        var low = 0, high = 1, _upperLimit = (upperLimit || 1024 * 1024 * 1024) / 2, upperTest = true;
        while ((upperTest = test(high)) && high < _upperLimit) { low = high; high *= 2; }
        if (!upperTest) {
            var half = ~~((high - low + 1) / 2); // (~~ is a faster Math.floor())
            high -= half;
            while (half > 0) high += (half = ~~(half / 2)) * (test(high) ? 1 : -1);
            high = testkey.length + high;
        }
        if (high > _upperLimit) high = _upperLimit;
        store.removeItem(testkey);
        for (var p in backup) store.setItem(p, backup[p]);
        return high * 2; // (*2 because of Unicode storage)
    }
    

    它还在测试前备份内容,然后恢复它们。

    它是如何工作的:它将大小翻倍,直到达到限制或测试失败。然后它存储低和高之间距离的一半,并每次减去/加上一半的一半(失败时减去,成功时加上);磨练成适当的价值。

    upperLimit 默认为 1GB,仅限制在开始二分搜索之前以指数方式向上扫描的距离。我怀疑这甚至需要改变,但我总是提前考虑。 ;)

    在 Chrome 上:

    > getStorageTotalSize();
    > 10485762
    > 10485762/2
    > 5242881
    > localStorage.setItem("a", new Array(5242880).join("0")) // works
    > localStorage.setItem("a", new Array(5242881).join("0")) // fails ('a' takes one spot [2 bytes])
    

    IE11、Edge 和 FireFox 也报告相同的最大大小(10485762 字节)。

    【讨论】:

    • (在测试前后不要忘记localStorage.Clear()
    • 不用了,这个功能已经清除了物品,之后再恢复。
    【解决方案9】:

    我正在做以下事情:

    getLocalStorageSizeLimit = function () {
    
        var maxLength = Math.pow(2,24);
        var preLength = 0;
        var hugeString = "0";
        var testString;
        var keyName = "testingLengthKey";
    
        //2^24 = 16777216 should be enough to all browsers
        testString = (new Array(Math.pow(2, 24))).join("X");
    
        while (maxLength !== preLength) {
            try  {
                localStorage.setItem(keyName, testString);
    
                preLength = testString.length;
                maxLength = Math.ceil(preLength + ((hugeString.length - preLength) / 2));
    
                testString = hugeString.substr(0, maxLength);
            } catch (e) {
                hugeString = testString;
    
                maxLength = Math.floor(testString.length - (testString.length - preLength) / 2);
                testString = hugeString.substr(0, maxLength);
            }
        }
    
        localStorage.removeItem(keyName);
    
        maxLength = JSON.stringify(this.storageObject).length + maxLength + keyName.length - 2;
    
        return maxLength;
    };
    

    【讨论】:

    • Maroun Maroun:再次查看帖子,作者提供了代码以编程方式检查本地存储的最大大小。这似乎是一个有效的答案,而不是另一个问题。
    • 在撰写本文时,执行此代码会在 Chrome 中引发“非法返回语句”错误
    【解决方案10】:

    我真的很喜欢cdmckay's answer,但是实时检查大小看起来并不好:它太慢了(对我来说是 2 秒)。这是改进后的版本,更快更准确,还可以选择误差的大小(默认250,000,误差越小 - 计算时间越长):

    function getLocalStorageMaxSize(error) {
      if (localStorage) {
        var max = 10 * 1024 * 1024,
            i = 64,
            string1024 = '',
            string = '',
            // generate a random key
            testKey = 'size-test-' + Math.random().toString(),
            minimalFound = 0,
            error = error || 25e4;
    
        // fill a string with 1024 symbols / bytes    
        while (i--) string1024 += 1e16;
    
        i = max / 1024;
    
        // fill a string with 'max' amount of symbols / bytes    
        while (i--) string += string1024;
    
        i = max;
    
        // binary search implementation
        while (i > 1) {
          try {
            localStorage.setItem(testKey, string.substr(0, i));
            localStorage.removeItem(testKey);
    
            if (minimalFound < i - error) {
              minimalFound = i;
              i = i * 1.5;
            }
            else break;
          } catch (e) {
            localStorage.removeItem(testKey);
            i = minimalFound + (i - minimalFound) / 2;
          }
        }
    
        return minimalFound;
      }
    }
    

    测试:

    console.log(getLocalStorageMaxSize()); // takes .3s
    console.log(getLocalStorageMaxSize(.1)); // takes 2s, but way more exact
    

    这对于标准错误的工作速度要快得多;必要时也可以更准确。

    【讨论】:

    • 仅供参考,尝试在 React 应用程序中使用此功能,但它会导致 iOS 上的所有移动浏览器崩溃:iOS 14.6 中的 Chrome、Safari、FF。
    【解决方案11】:

    您可以在现代浏览器中使用以下代码来有效地实时检查存储配额(总和已使用):

    if ('storage' in navigator && 'estimate' in navigator.storage) {
            navigator.storage.estimate()
                .then(estimate => {
                    console.log("Usage (in Bytes): ", estimate.usage,
                                ",  Total Quota (in Bytes): ", estimate.quota);
                });
    }
    

    【讨论】:

    • 不适用于 Chrome。 Usage (in Bytes): 647 , Total Quota (in Bytes): 32901464711 这是错误的:可能的总大小实际上是 10485762。
    • 不要使用它!我的 localStorage 绝对已满(无法写入),但估计说 Usage (in Bytes): 22849625 , Total Quota (in Bytes): 600121223577
    【解决方案12】:

    有一次我开发了 Chrome(桌面浏览器)扩展并测试了本地存储的实际最大大小。

    我的结果:

    Ubuntu 18.04.1 LTS (64-bit)
    Chrome 71.0.3578.98 (Official Build) (64-bit)
    Local Storage content size 10240 KB (10 MB)
    

    超过10240 KB 的使用返回了我的错误:

    未捕获的 DOMException:无法在“Storage”上执行“setItem”:设置“notes”的值超出了配额。

    2020 年 10 月 23 日编辑

    对于可用的 Chrome 扩展程序chrome.storage API。如果在manifest.js中声明“存储”权限:

    {
        "name": "My extension",
        ...
        "permissions": ["storage"],
        ...
    }
    

    你可以这样访问它:

    chrome.storage.local.QUOTA_BYTES // 5242880 (in bytes)
    

    【讨论】:

      猜你喜欢
      • 2013-02-26
      • 2012-06-30
      • 2011-03-13
      • 1970-01-01
      • 2015-11-08
      • 2016-04-17
      • 1970-01-01
      相关资源
      最近更新 更多