Расчет использования пространства localStorage
Я создаю приложение с помощью редактора Bespin и локального хранилища HTML5. Он хранит все файлы локально и помогает с грамматикой, использует JSLint и некоторые другие Парсеры для CSS и HTML, чтобы помочь пользователю.
Я хочу рассчитать, сколько предел localStorage был использован и сколько там на самом деле есть. возможно ли это сегодня? Я думал не просто вычислить биты, которые хранятся. Но опять же я не уверен, что еще есть, что я не могу измерить себя.
12 ответов:
вы можете получить приблизительную идею, используя методы JSON, чтобы превратить весь объект localStorage в строку JSON:
JSON.stringify(localStorage).lengthЯ не знаю, насколько байт-точным это будет, особенно с несколькими байтами добавленной разметки, если вы используете дополнительные объекты, но я считаю, что это лучше, чем думать, что вы только нажимаете 28K и вместо этого делаете 280K (или наоборот).
Я не нашел универсального способа получить оставшийся лимит на браузеры, которые мне нужны, но я узнал, что когда вы достигнете предела, появляется сообщение об ошибке. Это, конечно, отличается в каждом браузере.
чтобы максимизировать его, я использовал этот маленький скрипт:
for (var i = 0, data = "m"; i < 40; i++) { try { localStorage.setItem("DATA", data); data = data + data; } catch(e) { var storageSize = Math.round(JSON.stringify(localStorage).length / 1024); console.log("LIMIT REACHED: (" + i + ") " + storageSize + "K"); console.log(e); break; } } localStorage.removeItem("DATA");от этого я получил эту информацию:
Google Chrome
- DOMException:
- код: 22
- сообщение: "Не удалось выполнить' setItem 'на' Storage': установка значения' data ' превысила квоту."
- имя: "QuotaExceededError"
Mozilla Firefox
- DOMException:
- код: 1014
- сообщение: "достигнут максимальный размер постоянного хранилища"
- имя: "NS_ERROR_DOM_QUOTA_REACHED"
Safari
- DOMException:
- код: 22
- сообщение: "QuotaExceededError: исключение DOM 22"
- имя: "QuotaExceededError"
Internet Explorer, Edge (сообщества)
- DOMException:
- код: 22
- сообщение: "QuotaExceededError"
- имя: "QuotaExceededError"
мое решение
до сих пор мое решение заключается в добавлении дополнительного вызова каждый раз, когда пользователь будет сохранять что-либо. И если исключение будет поймано, тогда я скажу им, что у них заканчивается емкость хранилища.
изменить: удалить добавленные данные
Я забыл упомянуть, что для этого на самом деле работать вы нужно будет удалить
DATAэлемент, который был изначально установлен. Изменение отражено выше с помощью removeItem ()
IE8 реализует
remainingSpaceсвойство для этой цели:alert(window.localStorage.remainingSpace); // should return 5000000 when emptyк сожалению, похоже, что это не доступно в других браузерах. Однако я не уверен, что они реализуют что-то подобное.
вы можете использовать нижеприведенную строку для точного вычисления этого значения и вот jsfiddle для иллюстрации его использования
alert(1024 * 1024 * 5 - escape(encodeURIComponent(JSON.stringify(localStorage))).length);
столкнулся с этим сегодня во время тестирования (превышение квоты) и приготовил раствор. ИМО, зная, что такое предел и где мы находимся в отношении, гораздо менее ценно, чем реализация функционального способа продолжения хранения за пределами квоты.
таким образом, вместо того, чтобы пытаться делать сравнения размеров и проверки емкости, давайте реагировать, когда мы попали в квоту, уменьшить наше текущее хранилище на треть и возобновить хранение. Если указанное сокращение не удается, остановите сохраняющий.
set: function( param, val ) { try{ localStorage.setItem( param, typeof value == 'object' ? JSON.stringify(value) : value ) localStorage.setItem( 'lastStore', new Date().getTime() ) } catch(e){ if( e.code === 22 ){ // we've hit our local storage limit! lets remove 1/3rd of the entries (hopefully chronologically) // and try again... If we fail to remove entries, lets silently give up console.log('Local storage capacity reached.') var maxLength = localStorage.length , reduceBy = ~~(maxLength / 3); for( var i = 0; i < reduceBy; i++ ){ if( localStorage.key(0) ){ localStorage.removeItem( localStorage.key(0) ); } else break; } if( localStorage.length < maxLength ){ console.log('Cache data reduced to fit new entries. (' + maxLength + ' => ' + localStorage.length + ')'); public.set( param, value ); } else { console.log('Could not reduce cache size. Removing session cache setting from this instance.'); public.set = function(){} } } } }эта функция живет внутри объекта-оболочки, поэтому общедоступна.набор просто называет себя. Теперь мы можем добавить в хранилище и не беспокоиться, что квота или как близко мы тоже это. Если один магазин превышает 1/3 размер квоты, где эта функция прекратит отбраковку и прекратит хранение, и в этот момент Вы не должны кэшировать в любом случае, верно?
чтобы добавить в браузер результаты теста:
Firefox i=22.
сафари Версия 5.0.4 на моем Mac не висела. Ошибка как хром. i=21.
Опера Говорит пользователю, что веб-сайт хочет хранить данные, но не имеет достаточно места. Пользователь может отклонить запрос, увеличить лимит до требуемой суммы или до нескольких других лимитов, либо установить его неограниченным. Перейдите в opera: webstorage, чтобы узнать, появляется ли это сообщение или не. i=20. Ошибка брошена такая же, как Chrome.
режим стандартов IE9 Ошибка как хром. i=22.
IE9 в режиме стандартов IE8 Консольное сообщение "Ошибка: недостаточно памяти для выполнения этой операции". i=22
IE9 в старых режимах ошибка объекта. i=22.
IE8 У вас нет копии для тестирования, но локальное хранилище поддерживается (http://stackoverflow.com/questions/3452816/does-ie8-support-out-of-the-box-in-localstorage)
IE7 и ниже Не поддерживает локальное хранилище.
вы можете проверить свой браузер с этим тест поддержки веб-хранилища
Я проверял Firefox как на моем планшете android, так и на ноутбуке windows и хром только на windows результаты:
Firefox(windows):
- localStorage: 5120k char
- sessionStorage: 5120k чар
- localStorage: *не поддерживается
Firefox(android):
- localStorage: 2560k char
- sessionStorage: неограниченный (точно тест работает до 10240k char = = 20480k байт)
- localStorage:не поддерживается
хром(windows):
- localStorage: 5120k char
- sessionStorage: 5120k char
- localStorage:не поддерживается
обновление
на Google Chrome версии 52.0.2743.116 м (64-бит) пределы, где немного ниже
5101kсимволы. Это означает, что max available может изменяться в версиях.
жаль, что я не могу добавить это в комментарии - не хватает репутации, извините.
Я провел несколько тестов perf-ожидая JSON.stringify (localStorage).длина, чтобы быть дорогим op при большой занятости localStorage.
http://jsperf.com/occupied-localstorage-json-stringify-length
Это действительно так-примерно в 50 раз дороже, чем отслеживать то, что вы храните, и становится хуже, чем полнее localStorage получает.
эта функция возвращает точно хранилище / влево:
Я сделал набор полезных функций для localStorage *здесь*
http://jsfiddle.net/kzq6jgqa/3/
function getLeftStorageSize() { var itemBackup = localStorage.getItem(""); var increase = true; var data = "1"; var totalData = ""; var trytotalData = ""; while (true) { try { trytotalData = totalData + data; localStorage.setItem("", trytotalData); totalData = trytotalData; if (increase) data += data; } catch (e) { if (data.length < 2) break; increase = false; data = data.substr(data.length / 2); } } localStorage.setItem("", itemBackup); return totalData.length; } // Examples document.write("calculating.."); var storageLeft = getLeftStorageSize(); console.log(storageLeft); document.write(storageLeft + ""); // to get the maximum possible *clear* the storage localStorage.clear(); var storageMax = getLeftStorageSize();обратите внимание, что это не очень быстро, поэтому не используйте его все время.
С этим я также узнал, что: имя элемента займет столько же места, сколько его длина, значение элемента также займет столько же пространство как их длина.
максимальное хранение я получил-все о 5M:
- 5000000 символов края
- 5242880 символов - хром
- 5242880 символов-Firefox
- 5000000 символов-IE
вы найдете некоторые из-прокомментированный код в скрипке, чтобы увидеть прогресс в консоли.
мне потребовалось некоторое время, чтобы сделать, надеюсь, это поможет ☺
Мне нужно было фактически смоделировать и проверить, что мой модуль будет делать, когда хранилище заполнено, поэтому мне нужно было получить близкую точность, когда хранилище заполнено, а не принятый ответ, который теряет эту точность со скоростью i^2.
вот мой скрипт, который всегда должен производить точность 10 при достижении крышки памяти и довольно быстро, несмотря на некоторые простые оптимизации... EDIT: я сделал скрипт лучше и с точной точностью:
function fillStorage() { var originalStr = "1010101010"; var unfold = function(str, times) { for(var i = 0; i < times; i++) str += str; return str; } var fold = function(str, times) { for(var i = 0; i < times; i++) { var mid = str.length/2; str = str.substr(0, mid); } return str; } var runningStr = originalStr; localStorage.setItem("filler", runningStr); while(true) { try { runningStr = unfold(runningStr, 1); console.log("unfolded str: ", runningStr.length) localStorage.setItem("filler", runningStr); } catch (err) { break; } } runningStr = fold(runningStr, 1); var linearFill = function (str1) { localStorage.setItem("filler", localStorage.getItem("filler") + str1); } //keep linear filling until running string is no more... while(true) { try { linearFill(runningStr) } catch (err) { runningStr = fold(runningStr, 1); console.log("folded str: ", runningStr.length) if(runningStr.length == 0) break; } } console.log("Final length: ", JSON.stringify(localStorage).length) }
Это может кому-то помочь. В chrome можно попросить пользователя разрешить использовать больше места на диске при необходимости:
// Request Quota (only for File System API) window.webkitStorageInfo.requestQuota(PERSISTENT, 1024*1024, function(grantedBytes) { window.webkitRequestFileSystem(PERSISTENT, grantedBytes, onInitFs, errorHandler); }, function(e) { console.log('Error', e); });посещение https://developers.google.com/chrome/whitepapers/storage#asking_more для получения дополнительной информации.
try { var count = 100; var message = "LocalStorageIsNOTFull"; for (var i = 0; i <= count; count + 250) { message += message; localStorage.setItem("stringData", message); console.log(localStorage); console.log(count); } } catch (e) { console.log("Local Storage is full, Please empty data"); // fires When localstorage gets full // you can handle error here ot emply the local storage }
Comments