Каков максимальный размер значений localStorage?

542

Поскольку localStorage(в настоящее время) поддерживает только строки в качестве значений, и для этого объекты должны быть преобразованы в строку (сохранены как JSON-строки), прежде чем они могут быть сохранены, существует определенное ограничение относительно длины значений.

Кто-нибудь знает, есть ли определение, которое применяется ко всем браузерам?

Codekie
источник
15
Я думаю, что на самом деле никто не ответил на вопрос «Максимальная длина на значение».
Пит Элвин
@PeteAlvin Я только что ответил на вопрос .
user2428118
3
Все браузеры: html5rocks.com/en/tutorials/offline/quota-research
MCCCS
@PeteAlvin Кто-то ответил на это в 2015 году. Другие ответы касаются ограничения на общий размер, но не ограничения на размер на значение .
Али

Ответы:

420

Цитата из статьи Википедии о веб-хранилище :

Веб-хранилище можно рассматривать упрощенно как улучшение файлов cookie, обеспечивая гораздо большую емкость хранения ( 10 МБ на источник в Google Chrome ( https://plus.google.com/u/0/+FrancoisBeaufort/posts/S5Q9HqDB8bh ), Mozilla Firefox и Opera; 10 МБ на область хранения в Internet Explorer ) и улучшенные программные интерфейсы.

А также цитата из статьи Джона Ресига [опубликовано в январе 2007 года]:

Пространство для хранения

Подразумевается, что в DOM Storage у вас значительно больше места для хранения, чем в типичных ограничениях пользовательских агентов, налагаемых на Cookies. Однако предоставленная сумма не определена в спецификации и не передана агентом пользователя.

Если вы посмотрите на исходный код Mozilla, то увидите, что 5120 КБ - это размер хранилища по умолчанию для всего домена. Это дает вам значительно больше места для работы, чем обычный файл cookie размером 2 КБ.

Однако размер этой области хранения может быть настроен пользователем (таким образом, область хранения 5 МБ не гарантируется и не подразумевается) и пользовательским агентом (например, Opera может предоставить только 3 МБ - но только время покажет. )

Даниэль Вассалло
источник
28
@Cupidvogel нет, это означает, что each domain( origin) может хранить 5 МБ на любом отдельном клиенте. Данные хранятся на клиентском компьютере - localStorageмеханизм никак не взаимодействует между клиентами.
DanielB
6
Нет, я просто хотел убедиться, что одни и те же данные доступны на нескольких страницах для одного домена. Часто я нахожу фразы домена и страницы написаны как синонимы, поэтому просто хотел знать наверняка!
SexyBeast
9
Есть ли ограничение на одно значение? (Если у меня много флагов для хранения, насколько безопасно хранить его как JSON в одном свойстве?)
phtrivier
5
У меня Safari на 5 МБ и Chrome 39 на 10 МБ (не уверен, когда он был увеличен с 5 МБ). См. Эту статью html5rocks.com/en/tutorials/offline/quota-research
Союзник
18
@Cupidvogel: Нет, это не по доменам, а по происхождению , так как этот термин используется в отношении той же Политики происхождения и тому подобное: схема + хост + порт. http://example.comи https://example.comне одного происхождения (разные схемы). http://example.comи http://www.example.comне одного происхождения (разные хосты). http://example.comи http://example.com:8080не одного происхождения (разные порты). НТН. :-)
TJ Crowder
134

На самом деле Opera не имеет ограничения в 5 МБ. Предлагает увеличить лимит, поскольку приложения требуют большего. Пользователь может даже выбрать «Неограниченное хранилище» для домена.

Вы можете легко проверить ограничения / квоту localStorage самостоятельно.

Том Адлер
источник
50
Chrome больше не рушится ... Интересный момент: 5 МБ равны 2,5 миллионам символов в Chrome. Очевидно, что UFT16 используется для localStore.
Феликс Алкала
1
@FelixAlcala К сожалению, это приводит к сбою бета-версии Chrome 15.0.874.54 на Mac OS X. У меня был сбой на 1.500.000 символов.
Иван Вучица,
Он сломал Chrome на моем устройстве, также сбросил bckground, не удивляясь, хотя, мой телефон имеет так мало оперативной памяти, он не может справиться с глупым открытым приложением FLASHLIGHT, пока открыт Chrome.
Джек,
6
@FelixAlcala - На самом деле, JavaScript предоставляет UCS-2. Хотя это похоже на UFT16некоторые очень важные отличия ... в основном вращаются вокруг факта, что UCS-2 предшествует UFT.
Джереми Дж. Старчер
@FelixAlcala Считаете ли вы, что отображение количества символов, а также эквивалентного размера диска (например, 2700 КБ ~ = 5 274 КБ) является хорошей идеей?
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, сохраняя размер в килобайтах.

cdmckay
источник
1
Классное решение. Я нашел этот лайнер , что ты думаешь?
brasofilo
2
@brasofilo Я думаю, что один лайнер предполагает, что у вас есть 5 МБ, а затем вычитает используемую сумму.
cdmckay
Оооо, конечно выстрел. У меня проблема с вашим кодом - невозможность получить правильные результаты с помощью Правильного способа преобразования размера в байтах в КБ, МБ, ГБ в Javascript ... Я рассмотрю это завтра, но если вы посмотрите, оценили.
brasofilo
1
улучшил производительность и качество этого ответа здесь
smnbbrv
Сейчас 2020 год, и этот ответ прекрасно работает как на ванильном Chrome, так и на Firefox на Win10, давая размер = 5000.
А. Кьеза
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.

user2428118
источник
1
Забавно, но ваш простой тест останавливает мою довольно мощную систему, когда я тестирую в браузере Edge (на Win 10) после ~ 1 минуты запуска. Поэтому я не могу добавить новые данные к вашим результатам))
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
И никакой ссылки не было заполнено. Но для потомков эти цифры немного меняются. Мы должны обновить это мы больше браузеров и текущей информации.
Малавос
3
@ChrisLang добавил ссылку
Behnam Mohammadi
1
@Malavos добавил ссылку
Behnam Mohammadi
26

Не думайте, что доступно 5 МБ - емкость localStorage варьируется в зависимости от браузера: 2,5 МБ, 5 МБ и неограниченное количество являются наиболее распространенными значениями. Источник: http://dev-test.nemikor.com/web-storage/support-test/

Тагава
источник
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
Марун Марун: Проверьте почту еще раз, автор предоставил код для программной проверки максимального размера локального хранилища. Это действительно правильный ответ, а не другой вопрос.
Аренд
При выполнении этих кодов в Chrome возникает ошибка «Заявление о
недопустимом возврате»
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

Это работает значительно быстрее для стандартной ошибки; также это может быть намного точнее, когда это необходимо.

smnbbrv
источник
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по умолчанию равен 1 ГБ и ограничивает экспоненциальную скорость сканирования до начала двоичного поиска. Я сомневаюсь, что это даже нужно будет изменить, но я всегда думаю о будущем. ;)

На 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использование вернуло мне ошибку:

Uncaught DOMException: не удалось выполнить 'setItem' для 'Storage': установка значения 'notes' превысила квоту.

smokehill
источник
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

введите описание изображения здесь

И наполовину меньший результат в сафари ~ 2Mbytes

введите описание изображения здесь

gkucmierz
источник