Який максимальний розмір значень localStorage?


543

Оскільки localStorage(в даний час) підтримуються лише рядки як значення, і для цього об'єкти повинні бути поранені (зберігаються як JSON-рядок), перш ніж вони можуть бути збережені, чи є визначене обмеження щодо довжини значень.

Хтось знає, чи є визначення, яке стосується всіх браузерів?


15
Я думаю, що ніхто не відповідав на питання "максимальна довжина на значення".
Піт Елвін



@PeteAlvin Хтось відповів на нього у 2015 році. Інші відповіді стосуються обмеження загального розміру, але не обмеження розміру на значення .
Алі

Відповіді:


421

Цитуючи статтю у Вікіпедії про Веб-сховище :

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

А також цитуючи статтю Джона Ресіга [опубліковану в січні 2007 року]:

Місце для зберігання

Мається на увазі, що у DOM Storage ви маєте значно більше місця для зберігання даних, ніж типові обмеження для агента користувача, накладені на файли cookie. Однак сума, яка надається, не визначена в специфікації, а також не містить значущого трансляції користувальницьким агентом.

Якщо ви подивитеся на вихідний код Mozilla, ми можемо побачити, що 5120 КБ - це розмір пам’яті за замовчуванням для цілого домену. Це дає вам значно більше місця для роботи, ніж типовий cookie розміром 2 Кб.

Однак розмір цієї області зберігання може бути налаштований користувачем (тому область пам’яті 5 Мб не гарантується і не передбачається) та користувальницький агент (Опера, наприклад, може забезпечити лише 3 МБ), але покаже лише час. )


28
@Cupidvogel ні, це означає, що кожен 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не мають однакове походження (різні порти). HTH. :-)
TJ Crowder

134

Насправді Opera не має обмеження 5MB. Він пропонує збільшити ліміт, оскільки додатків вимагає більше. Користувач може навіть вибрати "Неограниченное хранилище" для домену.

Ви можете легко протестувати локальні обмеження / квоти самостійно.


50
Більше не виходить з ладу Chrome ... Цікавий момент: 5MB дорівнює 2,5 мільйона символів у Chrome. Отже, мабуть, UFT16 використовується для localStore.
Фелікс Алкала

1
@FelixAlcala На жаль, він вибиває бета-версію Chrome 15.0.874.54 на Mac OS X. У мене стався збій на 1.500.000 символів.
Іван Вучиця

Він зламав хром на моєму пристрої, також скинув bckground, але не здивований, хоча у мого телефону є така маленька оперативна пам’ять, він не може впоратися з тим, що дурне додаток FLASHLIGHT відкрите, поки хром відкритий.
Джек

6
@FelixAlcala - насправді, JavaScript відкриває UCS-2. Хоча це схоже на UFT16деякі дуже важливі відмінності ... в основному обертаються навколо того, що UCS-2 передує UFT.
Джеремі Дж. Старчер

@FelixAlcala Ви вважаєте, що відображення кількості символів, а також його еквівалентного розміру диска (наприклад, 2 700 К символів ~ = 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 та допис у блозі .

Сценарій перевіряє налаштування дедалі більших рядків тексту до тих пір, поки браузер не кине і не виключить. Після цього він очистить дані тесту та встановить клавішу розміру в локальному сховищі, зберігаючи розмір у кілобайт.


1
Прохолодний розчин. Я знайшов цей один лайнер , як ви думаєте?
brasofilo

2
@brasofilo Я думаю, що один вкладиш припускає, що у вас є 5 Мб, а потім віднімає використану суму.
cdmckay

Оооо, впевнений постріл. Проблема, що виникає у вас з вашим кодом, не в змозі отримати правильні результати за допомогою правильного способу перетворення розміру в байти в KB, MB, GB в Javascript ... Я перегляну це завтра, але якщо ви можете поглянути, цінується.
brasofilo

1
покращили ефективність та якість цієї відповіді тут
smnbbrv

Настає 2020 рік, і ця відповідь прекрасно працює як на ванільному Chrome, так і на Firefox на Win10, даючи розмір = 5000.
A. Chiesa

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 додав посилання
Бенах Мохаммаді


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". Зараз це лише серіалізатор, чорнило дуже мокре, але це швидше, ніж рабуб, і однаково універсальне. Рабу незабаром перетворять для його внутрішнього використання.
Адріан

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: Перевірте публікацію ще раз, автор надав код для програмної перевірки максимального розміру локального сховища. Це здається, що це правильна відповідь, а не інше питання.
Аренд

Виконання цього коду
призводить до

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 (настільний браузер) і перевірив справжній максимальний розмір Local Storage з цієї причини.

Мої результати:

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, хоробрий та мобільний хром, який становить ~ 5 Мбайт

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

І вдвічі менший результат у сафарі ~ 2 Мбайт

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.