Каков максимальный размер значений localStorage? - PullRequest
472 голосов
/ 07 июня 2010

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

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

Ответы [ 12 ]

383 голосов
/ 07 июня 2010

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

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

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

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

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

Если вы посмотрите на исходный код Mozilla мы можем видеть, что 5120KB по умолчанию Размер хранилища для всего домена. Это дает вам значительно больше места работать с чем типичным 2KB печенье.

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

121 голосов
/ 16 июля 2010

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

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

66 голосов
/ 12 сентября 2014

Вот простой скрипт для определения предела:

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

27 голосов
/ 18 февраля 2017

Мобильные браузеры:

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

Ссылочная ссылка

25 голосов
/ 12 октября 2015

Найти максимальную длину отдельной строки, которая может быть сохранена в 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.

24 голосов
/ 10 февраля 2012

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

13 голосов
/ 01 октября 2014

Вы не хотите объединять большие объекты в одну запись localStorage. Это было бы очень неэффективно - все это нужно было бы анализировать и перекодировать каждый раз, когда вносятся небольшие изменения в детали. Кроме того, JSON не может обрабатывать несколько перекрестных ссылок в структуре объекта и стирает много деталей, например, конструктор, нечисловые свойства массивов, что находится в разреженной записи и т. д.

Вместо этого вы можете использовать Rhaboo . Он хранит большие объекты, используя множество записей localStorage, поэтому вы можете быстро вносить небольшие изменения. Восстановленные объекты являются гораздо более точными копиями сохраненных, а API невероятно прост. E.g.:

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

Кстати, я написал это.

6 голосов
/ 14 марта 2016

Мне действительно нравится ответ 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

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

5 голосов
/ 21 мая 2018

Вы можете использовать следующий код в современных браузерах для эффективной проверки квоты хранилища (всего и использованного) в реальном времени:

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);
            });
}
4 голосов
/ 21 марта 2019

Я сжал бинарный тест в этой функции, которую я использую:

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 байта).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...