localStorage值的最大大小是多少?


542

以来 localStorage(当前)仅支持将字符串用作值,并且为了做到这一点,需要先对对象进行字符串化(存储为JSON-string),然后才能存储它们,因此对值的长度存在定义的限制。

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


15
我认为没有人真正回答“每个值的最大长度”问题。
皮特·阿尔文

@PeteAlvin我刚刚回答了问题
user2428118


@PeteAlvin有人在2015年回答了这个问题。其他回答是针对总大小的限制,而不是针对每个值的大小的限制。
阿里(Ali)

Answers:


421

引用有关Web存储Wikipedia文章

可以简单地将网络存储视为Cookie的一种改进,它提供了更大的存储容量(Google Chrome中每个原始站点10 MB(https://plus.google.com/u/0/+FrancoisBeaufort/posts/S5Q9HqDB8bh),Mozilla Firefox和Opera;在Internet Explorer中每个存储区10 MB)和更好的编程界面。

并且引用了John Resig的文章 [发布于2007年1月]:

储存空间

暗示,使用DOM存储,您具有比对Cookie施加的典型用户代理限制更大的存储空间。但是,提供的数量没有在规范中定义,用户代理也没有有意义地广播。

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

但是,该存储区的大小可以由用户自定义(因此,不能保证5MB的存储区,也没有暗示),并且用户代理(例如,Opera只能提供3MB的存储空间,但是只有时间能说明问题)。 )


28
@Cupidvogel不,这意味着每个domainorigin)可以在任何单个客户端上存储5MB。数据存储在客户端计算机上-该localStorage机制绝不会在客户端之间进行交互。
DanielB 2013年

6
不,我只是想确保可以跨同一域的多个页面访问相同的数据。我经常会发现词组域和页面是同义词,所以只想确定一下就知道了!
SexyBeast 2013年

9
但是,单个值是否有限制?(如果我要存储很多标志,将其作为JSON存储在单个属性中有多安全?)
phtrivier 2013年

5
我有5MB的Safari和10MB的Chrome 39(不确定何时从5MB提升),请参阅本文html5rocks.com/en/tutorials/offline/quota-research
Ally

18
@Cupidvogel:不,不是按域,而是按来源,因为该术语是针对“相同来源策略”,例如scheme + host + port。http://example.com并且https://example.com来源不同(方案不同)。http://example.com并且http://www.example.com不是同一来源(不同的主机)。http://example.com并且http://example.com:8080来源不同(端口不同)。HTH。:-)
TJ Crowder 2015年

133

实际上,Opera没有5MB的限制。随着应用程序需求的增加,它提供了增加限制的功能。用户甚至可以为域选择“无限存储”。

您可以轻松地自己测试localStorage限制/配额


50
不会再使Chrome崩溃了……有趣的是:5MB等于Chrome上250万个字符。因此,显然,UFT16用于localStore。
菲利克斯·阿尔卡拉

1
@FelixAlcala不幸的是,它使Mac OS X上的Chrome 15.0.874.54 beta版崩溃了。我的崩溃次数为1.500.000个字符。
伊凡·武西卡(IvanVučica)2011年

它使我的设备上的chrome崩溃了,也重置了背景,尽管如此,我的手机只有这么少的RAM,当chrome打开时,它无法处理打开一个愚蠢的FLASHLIGHT APP的情况也就不足为奇了。
2014年

6
@FelixAlcala-实际上,JavaScript公开了UCS-2。尽管它类似于,UFT16但还是有一些非常重要的区别……主要围绕UCS-2早于UFT的事实。
Jeremy J Starcher

@FelixAlcala您认为显示几个字符及其等效磁盘大小(例如2,700K个字符〜= 5,274 KB)是一个好主意吗?
许志安(AJ Hsu)

76

这是找出限制的简单脚本:

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);            
    }
}

这是要点JSFiddle博客文章

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


1
很酷的解决方案。我找到了这支班轮,您怎么看?
brasofilo

2
@brasofilo我认为一个班轮假设您有5MB,然后减去使用的金额。
cdmckay

哎呀,确定射击。我的代码存在的问题是无法通过正确的方法将Java中的字节大小转换为KB,MB,GB的方式来获得正确的结果...明天我将对此进行修改,但是如果您可以看一下,赞赏。
brasofilo

1
改进的性能和这个答案的质量这里
smnbbrv

现在是2020年,这个答案在Win10上的普通Chrome和Firefox上都可以正常使用,大小为5000。
A.基耶萨

34

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

此代码段将查找可以在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不限于单个字符串时可以存储的最大数据量,则可以使用此答案中的代码

编辑:堆栈片段不支持localStorage,因此这是指向JSFiddle的链接

结果

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

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


1
有趣,但是当运行约1分钟后,当我在Edge浏览器(在Win 10上)进行测试时,您的简单测试使我强大的系统停止运行。因此,我无法将新数据添加到您的结果中))
vatavale

33

移动浏览器:

Browser    | Chrome    | Android Browser    | Firefox     | iOS Safari
Version    | 40        | 4.3                | 34          | 6-8
Available  | 10MB      | 2MB                | 10MB        | 5MB

桌面浏览器:

Browser    | Chrome   | Opera    | Firefox    | Safari      | IE
Version    | 40       | 27       | 34         | 6-8         | 9-11
Available  | 10MB     | 10MB     | 10MB       | 5MB         | 10MB

参考链接


6
数字从哪里来?
MrD

23
@BehnamMohammadi您可以添加参考以获取完整性的原因吗?
克里斯·朗

1
而且没有参考文献被填写。但是对于后代,这些数字有所变化。我们应该通过更多浏览器和当前信息对其进行更新。
马拉沃斯'18

3
@ChrisLang添加了链接
Behnam Mohammadi

1
@Malavos添加了链接
Behnam Mohammadi


13

您不想将大对象分成单个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');

顺便说一句,我写的。


1
谢谢马丁。您也可以检查我的“ evon”存储库。现在它只是一个序列化器,墨水很湿,但是它比rhaboo快,并且用途广泛。Rhaboo将很快转换为在内部使用。
阿德里安

7
有用,但我认为这不能解决“ localStorage的最大大小是多少?”这个问题。通过说明该库尝试存储超出大小限制的内容时发生的情况以及如何对此做出反应,可以改善您的答案。
克里斯·莫斯基尼

6

我正在执行以下操作:

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;
};

5
Maroun Maroun:再次检查该帖子,作者提供了代码以编程方式检查本地存储的最大大小。这似乎是一个有效的答案,而不是另一个问题。
2015年

截至撰写本文时,执行此代码会在Chrome中引发“非法返回声明”错误
-DrewT

6

我真的很喜欢cdmckay的答案,但是实时检查大小看起来并不好:太慢了(对我来说是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

对于标准错误,这可以更快地工作。必要时也可以更加精确。


6

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

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字节)。


1
(并且不要忘记localStorage.Clear()测试之前和之后
simonmysun

5

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

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.
詹姆斯威尔金斯

1

因此,一旦我开发了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:无法在“存储”上执行“ setItem”:设置“便笺”的值超出了配额。


0

我写了这个简单的代码,以字节为单位测试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

在此处输入图片说明

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.