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


542

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

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


15
Я думаю, что на самом деле никто не ответил на вопрос «Максимальная длина на значение».
— Пит Элвин

@PeteAlvin Я только что ответил на вопрос .
— user2428118


@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, сохраняя размер в килобайтах.


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.


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

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


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' превысила квоту.


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

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.