it-swarm.asia

ما هو الحد الأقصى لحجم قيم localStorage؟

نظرًا لأن localStorage (حاليًا) يدعم فقط السلاسل كقيم ، ومن أجل القيام بذلك ، تحتاج الكائنات إلى توحيد (تخزينها كسلسلة JSON) قبل أن يمكن تخزينها ، هل هناك قيود محددة فيما يتعلق بطول القيم.

هل يعرف أحد ما إذا كان هناك تعريف ينطبق على جميع المتصفحات؟

465
Prjio

اقتباس من مقالة ويكيبيديا على تخزين الويب :

يمكن النظر إلى مساحة التخزين على الويب بشكل بسيط باعتبارها تحسينًا على ملفات تعريف الارتباط ، مما يوفر سعة تخزينية أكبر ( 10 ميغابايت لكل أصل في Google Chrome ( https://plus.google.com/u/0/+FrancoisBeaufort/posts/S5Q9HqDB8bh ) و Mozilla Firefox و Opera ؛ 10 ميغابايت لكل مساحة تخزين في Internet Explorer ) واجهات برمجية أفضل.

واقتباسًا أيضًا من John Resig article [تم النشر في يناير 2007]:

مساحة التخزين

يعني ذلك أنه مع تخزين DOM ، لديك مساحة تخزين أكبر بكثير من قيود وكيل المستخدم النموذجية المفروضة على ملفات تعريف الارتباط. ومع ذلك ، لا يتم تحديد المبلغ الذي يتم توفيره في المواصفات ، كما أنه لا يتم بثه بشكل مفيد بواسطة وكيل المستخدم.

إذا نظرت إلى شفرة مصدر Mozilla ، يمكننا أن نرى أن 5120 كيلو بايت هو حجم التخزين الافتراضي لنطاق بأكمله. يمنحك هذا مساحة أكبر بكثير للعمل من ملف تعريف الارتباط 2KB النموذجي.

ومع ذلك ، يمكن تخصيص حجم مساحة التخزين هذه بواسطة المستخدم (بحيث لا تكون مساحة التخزين 5 ميجابايت مضمونة ، كما أنها ليست ضمنية) وكيل المستخدم (Opera ، على سبيل المثال ، قد يوفر فقط 3 ميجابايت - ولكن المرة الوحيدة التي سوف اقول.)

378
Daniel Vassallo

في الواقع ليس لدى Opera حد 5 ميغابايت. إنه يوفر زيادة الحد لأن التطبيقات تتطلب المزيد. يمكن للمستخدم حتى اختيار "تخزين غير محدود" للمجال.

يمكنك بسهولة اختبار localStorage حدود/الحصص نفسك.

121
Artemy Tregubenko

إليك نصًا بسيطًا لمعرفة الحد الأقصى:

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

إليك The Gist ، JSFiddle و مدونة بعد .

سيختبر البرنامج النصي إعداد سلاسل نصية أكبر على نحو متزايد حتى يلقي المتصفح ويستثنى منه. في هذه المرحلة ، سيتم مسح بيانات الاختبار وتعيين مفتاح حجم في تخزين محلي يخزن الحجم بالكيلو بايت.

65
cdmckay

ابحث عن الحد الأقصى لطول السلسلة الفردية التي يمكن تخزينها في 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) 16386122066 122070 حرفا

أحصل على نتائج مختلفة في كل تشغيل في Internet Explorer.

24
user2428118

لا تفترض أن سعة 5 ميجابايت متوفرة - تختلف سعة التخزين المحلي حسب المتصفح ، حيث تكون القيم الأكثر شيوعًا هي 2.5 ميغابايت و 5 ميجابايت. المصدر: http://dev-test.nemikor.com/web-storage/support-test/

24
tagawa

متصفحات الجوال:

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

الرابط المرجعي

21
Behnam Mohammadi

لا تريد توحيد الكائنات الكبيرة في إدخال 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');

راجع للشغل ، لقد كتبت ذلك.

13
Adrian May

يعجبني حقًا إجابة cdmckay ، لكن لا يبدو جيدًا حقًا التحقق من الحجم في الوقت الحقيقي: إنه بطيء جدًا (ثانيتين بالنسبة لي). هذه هي النسخة المحسّنة ، والتي هي أسرع بكثير وأكثر دقة ، مع وجود خيار لاختيار حجم الخطأ الكبير (الافتراضي 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
smnbbrv

يمكنك استخدام الكود التالي في المتصفحات الحديثة للتحقق من حصة التخزين (الإجمالي والمستهلك) بكفاءة في الوقت الفعلي:

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

أفعل ما يلي:

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;
};
4
Itay Merchav

لقد قمت بتكثيف اختبار ثنائي لهذه الوظيفة التي أستخدمها:

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 بايت).

3
James Wilkins

بمجرد قيامي بتطوير متصفح 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" على "التخزين": تعيين قيمة "الملاحظات" تجاوز الحصة.

1
smokehill