Kích thước tối đa của các giá trị localStorage là gì?


542

localStorage(hiện tại) chỉ hỗ trợ các chuỗi dưới dạng các giá trị và để làm được điều đó, các đối tượng cần được xâu chuỗi (được lưu dưới dạng chuỗi JSON) trước khi chúng có thể được lưu trữ, có giới hạn xác định về độ dài của các giá trị.

Có ai biết nếu có một định nghĩa áp dụng cho tất cả các trình duyệt?


15
Tôi nghĩ rằng không ai thực sự trả lời câu hỏi "độ dài tối đa trên mỗi giá trị".
Pete Alvin

@PeteAlvin Mình mới trả lời câu hỏi .
dùng2428118

3
Tất cả các trình duyệt: html5rocks.com/en/tutorials/offline/quota-research
MCCCS

@PeteAlvin Ai đó đã trả lời nó vào năm 2015. Các câu trả lời khác giải quyết giới hạn về tổng kích thước, nhưng không giới hạn kích thước trên mỗi giá trị .
Ali

Câu trả lời:


420

Trích dẫn từ bài viết Wikipedia về Lưu trữ web :

Lưu trữ web có thể được xem đơn giản là một cải tiến về cookie, cung cấp dung lượng lưu trữ lớn hơn nhiều ( 10 MB cho mỗi nguồn gốc trong Google Chrome ( https://plus.google.com/u/0/+FrancoisBeaufort/posts/S5Q9HqDB8bh ), Mozilla Firefox và Opera, 10 MB cho mỗi vùng lưu trữ trong Internet Explorer ) và giao diện lập trình tốt hơn.

Và cũng trích dẫn từ một bài báo của John Resig [đăng tháng 1 năm 2007]:

Không gian lưu trữ

Nó được ngụ ý rằng, với DOM Storage, bạn có không gian lưu trữ lớn hơn đáng kể so với các giới hạn tác nhân người dùng thông thường được áp dụng cho Cookies. Tuy nhiên, số lượng được cung cấp không được xác định trong thông số kỹ thuật và cũng không được truyền phát một cách có ý nghĩa bởi tác nhân người dùng.

Nếu bạn nhìn vào mã nguồn Mozilla, chúng ta có thể thấy 5120KB là kích thước lưu trữ mặc định cho toàn bộ miền. Điều này cung cấp cho bạn nhiều không gian để làm việc hơn so với cookie 2KB thông thường.

Tuy nhiên, kích thước của vùng lưu trữ này có thể được tùy chỉnh bởi người dùng (vì vậy vùng lưu trữ 5 MB không được đảm bảo, cũng không ngụ ý) và tác nhân người dùng (ví dụ, Opera chỉ có thể cung cấp 3 MB - nhưng chỉ có thời gian mới trả lời. )


28
@Coolvogel không, điều đó có nghĩa là mỗi domain( origin) có thể lưu trữ 5MB trên bất kỳ ứng dụng khách nào. Dữ liệu được lưu trữ trên máy khách - localStoragecơ chế không tương tác giữa các máy khách.
DanielB

6
Không, tôi chỉ muốn đảm bảo rằng cùng một dữ liệu có thể truy cập được trên nhiều trang cho cùng một tên miền. Thường thì tôi tìm thấy cụm từ tên miền và trang được đánh vần đồng nghĩa, vì vậy chỉ muốn biết chắc chắn!
SexyBeast

9
Có, tuy nhiên, một hạn chế trên một đơn giá trị? (Nếu tôi có rất nhiều cờ để lưu trữ, thì an toàn đến mức nào khi lưu trữ dưới dạng JSON trong một thuộc tính?)
phtrivier

5
Tôi đã có Safari ở mức 5MB và Chrome 39 ở mức 10 MB (không chắc chắn khi nào nó được tăng từ 5 MB) Xem bài viết này html5rocks.com/en/tutorials/offline/quota-research
Ally

18
@Coolvogel: Không, không phải theo tên miền, đó là theo nguồn gốc , vì thuật ngữ này được sử dụng theo Chính sách xuất xứ tương tự và như vậy: lược đồ + máy chủ + cổng. http://example.comhttps://example.comkhông cùng nguồn gốc (các sơ đồ khác nhau). http://example.comhttp://www.example.comkhông cùng nguồn gốc (các máy chủ khác nhau). http://example.comhttp://example.com:8080không cùng nguồn gốc (các cổng khác nhau). HTH. :-)
TJ Crowder

134

Thực tế Opera không có giới hạn 5 MB. Nó cung cấp để tăng giới hạn vì các ứng dụng đòi hỏi nhiều hơn. Người dùng thậm chí có thể chọn "Lưu trữ không giới hạn" cho một miền.

Bạn có thể dễ dàng tự kiểm tra giới hạn / hạn ngạch của LocalStorage .


50
Không sập Chrome nữa ... Điểm thú vị: 5MB tương đương 2,5 triệu ký tự trên Chrome. Vì vậy, rõ ràng, UFT16 được sử dụng cho localStore.
Felix Alcala

1
@FelixAlcala Thật không may, nó bị sập Chrome 15.0.874.54 beta trên Mac OS X. Tôi đã gặp sự cố ở 1.500.000 ký tự.
Ivan Vučica

Nó bị sập chrome trên thiết bị của tôi, cũng thiết lập lại bckground, mặc dù vậy, điện thoại của tôi có RAM ít như vậy, nó không thể mở ứng dụng FLASHLIGHT APP ngu ngốc khi chrome đang mở.
Jack

6
@FelixAlcala - Trên thực tế, JavaScript phơi bày UCS-2. Mặc dù tương tự như UFT16có một số khác biệt rất quan trọng ... chủ yếu xoay quanh thực tế là UCS-2 có trước UFT.
Jeremy J Starcher

@FelixAlcala Bạn có nghĩ rằng hiển thị bao nhiêu ký tự cũng như kích thước đĩa của nó tương đương (ví dụ 2.700K ký tự ~ = 5,274 KB) là một ý tưởng tốt?
AJ Hsu

76

Đây là một kịch bản đơn giản để tìm ra giới hạn:

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

Đây là ý chính , JSFiddlebài đăng trên blog .

Tập lệnh sẽ kiểm tra cài đặt các chuỗi văn bản ngày càng lớn hơn cho đến khi trình duyệt ném và ngoại lệ. Tại thời điểm đó, nó sẽ xóa dữ liệu thử nghiệm và đặt khóa kích thước trong localStorage lưu trữ kích thước tính bằng kilobyte.


1
Dung dịch mát. Tôi tìm thấy một lót này , bạn nghĩ gì?
brasofilo

2
@brasofilo Tôi nghĩ rằng một lớp lót giả sử bạn có 5 MB và sau đó trừ đi số tiền đang sử dụng.
cdmckay

Ooook, bắn chắc chắn. Vấn đề tôi gặp phải với mã của bạn là không thể có được kết quả chính xác với Cách chính xác để chuyển đổi kích thước theo byte thành KB, MB, GB trong Javascript ... Tôi sẽ sửa lại vào ngày mai nhưng nếu bạn có thể xem, đánh giá cao.
brasofilo

1
cải thiện hiệu suất và chất lượng của câu trả lời này tại đây
smnbbrv

Đó là năm 2020 và câu trả lời này hoạt động hoàn toàn tốt trên cả vanilla Chrome và Firefox trên Win10, cho kích thước = 5000.
A. Chiesa

34

Tìm độ dài tối đa của một chuỗi có thể được lưu trữ trong localStorage

Đoạn mã này sẽ tìm thấy độ dài tối đa của Chuỗi có thể được lưu trữ trong localStoragemỗi tên miền.

//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>

Lưu ý rằng độ dài của chuỗi bị giới hạn trong JavaScript; nếu bạn muốn xem lượng dữ liệu tối đa có thể được lưu trữ localStoragekhi không giới hạn trong một chuỗi, bạn có thể sử dụng mã trong câu trả lời này .

Chỉnh sửa: Stack Snippets không hỗ trợ localStorage, vì vậy đây là một liên kết đến JSFiddle .

Các kết quả

Chrome (45.0.2454.101): 5242878 ký tự
Firefox (40.0.1): 5242883 ký tự
Internet Explorer (11.0.9600.18036) :16386 122066 122070 ký tự

Tôi nhận được kết quả khác nhau trên mỗi lần chạy trong Internet Explorer.


1
Hài hước, nhưng bài kiểm tra đơn giản của bạn đã chặn hệ thống khá mạnh của tôi khi tôi kiểm tra trong trình duyệt Edge (trên Win 10) sau ~ 1 phút chạy. Vì vậy, tôi không thể nối dữ liệu mới vào kết quả của bạn))
vatavale

33

Trình duyệt di động:

Browser    | Chrome    | Android Browser    | Firefox     | iOS Safari
Version    | 40        | 4.3                | 34          | 6-8
Available  | 10MB      | 2MB                | 10MB        | 5MB

Trình duyệt máy tính để bàn:

Browser    | Chrome   | Opera    | Firefox    | Safari      | IE
Version    | 40       | 27       | 34         | 6-8         | 9-11
Available  | 10MB     | 10MB     | 10MB       | 5MB         | 10MB

liên kết tham khảo


6
Những con số đến từ đâu?
MrD

23
@BehnamMohammadi bạn có thể thêm một tài liệu tham khảo đến nơi bạn đã nhận được điều này từ sự hoàn chỉnh
Chris Lang

1
Và không có tài liệu tham khảo nào được điền vào. Nhưng đối với hậu thế, những con số này thay đổi một chút. Chúng tôi nên cập nhật điều này, chúng tôi thêm trình duyệt và thông tin hiện tại.
Malavos

3
@ChrisLang đã thêm liên kết
Behnam Mohammadi

1
@Malavos đã thêm liên kết
Behnam Mohammadi


13

Bạn không muốn xâu chuỗi các đối tượng lớn vào một mục LocalStorage duy nhất. Điều đó sẽ rất không hiệu quả - toàn bộ mọi thứ sẽ phải được phân tích cú pháp và mã hóa lại mỗi khi một số thay đổi chi tiết nhỏ. Ngoài ra, JSON không thể xử lý nhiều tham chiếu chéo trong cấu trúc đối tượng và xóa sạch rất nhiều chi tiết, ví dụ: hàm tạo, thuộc tính không phải là số của mảng, những gì trong một mục nhập thưa thớt, v.v.

Thay vào đó, bạn có thể sử dụng Rhaboo . Nó lưu trữ các đối tượng lớn bằng cách sử dụng nhiều mục LocalStorage để bạn có thể thực hiện các thay đổi nhỏ một cách nhanh chóng. Các đối tượng được khôi phục là bản sao chính xác hơn của các đối tượng đã lưu và API cực kỳ đơn giản. Ví dụ:

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

BTW, tôi đã viết nó.


1
Cảm ơn Martin. Bạn cũng có thể kiểm tra repo 'evon' của tôi. Nó chỉ là một serializer ngay bây giờ và mực rất ướt, nhưng nó nhanh hơn rhaboo và linh hoạt không kém. Rhaboo sẽ sớm được chuyển đổi để sử dụng nó trong nội bộ.
Adrian ngày

7
Hữu ích nhưng tôi không nghĩ rằng điều này giải quyết câu hỏi "Kích thước tối đa của localStorage là gì;" câu trả lời của bạn có thể được cải thiện bằng cách nêu rõ điều gì xảy ra khi thư viện này cố lưu trữ thứ gì đó vượt quá giới hạn kích thước và cách phản ứng với nó.
Chris Moschini

6

Tôi đang làm như sau:

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: Kiểm tra lại bài đăng, tác giả đã cung cấp mã để kiểm tra theo chương trình kích thước tối đa của bộ nhớ cục bộ. Đây dường như là một câu trả lời hợp lệ, và không phải là một câu hỏi khác.
Arend

Việc thực thi mã này sẽ gây ra lỗi "Tuyên bố hoàn trả bất hợp pháp" trong Chrome, tại thời điểm viết bài
DrewT

6

Tôi thực sự thích câu trả lời của cdmckay , nhưng nó không thực sự tốt để kiểm tra kích thước trong thời gian thực: nó quá chậm (đối với tôi 2 giây). Đây là phiên bản cải tiến, nhanh hơn và chính xác hơn, cũng với tùy chọn chọn mức độ lớn của lỗi (mặc định 250,000, lỗi nhỏ hơn - tính toán càng dài):

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

Để kiểm tra:

console.log(getLocalStorageMaxSize()); // takes .3s
console.log(getLocalStorageMaxSize(.1)); // takes 2s, but way more exact

Điều này hoạt động nhanh hơn đáng kể cho các lỗi tiêu chuẩn; ngoài ra nó có thể chính xác hơn nhiều khi cần thiết.


6

Tôi đã cô đọng một bài kiểm tra nhị phân vào chức năng này mà tôi sử dụng:

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

Nó cũng sao lưu nội dung trước khi thử nghiệm, sau đó khôi phục chúng.

Cách thức hoạt động: Nó nhân đôi kích thước cho đến khi đạt đến giới hạn hoặc thử nghiệm thất bại. Sau đó, nó lưu trữ một nửa khoảng cách giữa thấp và cao và trừ / thêm một nửa của một nửa mỗi lần (trừ vào thất bại và thêm vào thành công); mài giũa vào giá trị thích hợp.

upperLimitlà 1GB theo mặc định và chỉ giới hạn mức độ quét lên theo cấp số nhân trước khi bắt đầu tìm kiếm nhị phân. Tôi nghi ngờ điều này thậm chí sẽ cần phải được thay đổi, nhưng tôi luôn suy nghĩ về phía trước. ;)

Trên 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 và FireFox cũng báo cáo kích thước tối đa tương tự (10485762 byte).


1
(Và đừng quên localStorage.Clear()trước và sau khi thử nghiệm
simonmysun

5

Bạn có thể sử dụng mã sau trong các trình duyệt hiện đại để kiểm tra hiệu quả dung lượng lưu trữ (tổng số & đã sử dụng) trong thời gian thực:

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

Không hoạt động tốt cho Chrome. Usage (in Bytes): 647 , Total Quota (in Bytes): 32901464711 Điều đó là sai: tổng kích thước có thể thực sự là 10485762.
James Wilkins

1

Khi tôi đã phát triển tiện ích mở rộng Chrome (trình duyệt máy tính để bàn) và đã thử nghiệm kích thước tối đa thực của Bộ lưu trữ cục bộ vì lý do này.

Kết quả của tôi:

Ubuntu 18.04.1 LTS (64-bit)
Chrome 71.0.3578.98 (Official Build) (64-bit)
Local Storage content size 10240 KB (10 MB)

Nhiều hơn 10240 KBviệc sử dụng trả lại cho tôi lỗi:

Uncaught DOMException: Không thể thực thi 'setItem' trên 'Storage': Đặt giá trị của 'ghi chú' vượt quá hạn ngạch.


0

Tôi đã viết mã đơn giản này đang kiểm tra kích thước localStorage theo byte.

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

Trang Github:

https://gkucmierz.github.io/Test-of-localStorage-limits-quota/

Tôi có kết quả tương tự trên chrome máy tính để bàn, opera, firefox, chrome dũng cảm và di động là ~ 5Mbyte

nhập mô tả hình ảnh ở đây

Và một nửa kết quả nhỏ hơn trong safari ~ 2Mbyte

nhập mô tả hình ảnh ở đây

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.