BespinエディターとHTML5のlocalStorageを使用してアプリを作成しています。すべてのファイルをローカルに保存し、文法を支援し、JSLintおよびCSSおよびHTMLの他のパーサーを使用してユーザーを支援します。
LocalStorage制限のどれだけが使用され、実際にどれだけあるかを計算したいと思います。 今日これは可能ですか?格納されているビットを単純に計算しないことを考えていました。しかし、再び、私は自分自身を測定することはできませんがそれ以上何があるかわかりません。
必要なブラウザの残りの制限を取得する普遍的な方法は見つかりませんでしたが、制限に達すると、ポップアップするエラーメッセージがあることがわかりました。もちろん、これはブラウザごとに異なります。
それを最大限に活用するために、この小さなスクリプトを使用しました。
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
Mozilla Firefox
サファリ
Internet Explorer、Edge(コミュニティ)
私の解決策
これまでのところ、私の解決策は、ユーザーが何かを保存するたびに余分な呼び出しを追加することです。そして、例外がキャッチされたら、ストレージ容量が不足していることを伝えます。
編集:追加したデータを削除します
これを実際に機能させるには、元々設定されていたDATA
アイテムを削除する必要があることを忘れていました。 removeItem() 関数を使用すると、上記の変更が反映されます。
JSONメソッドを使用してlocalStorageオブジェクト全体をJSON文字列に変換することで、おおよそのアイデアを得ることができる場合があります。
JSON.stringify(localStorage).length
特に追加のオブジェクトを使用している場合、数バイトのマークアップが追加されているため、バイト精度がどれほど正確かはわかりませんが、28Kだけを押して280Kを実行する(またはその逆)と考えるよりも良いと思います逆)。
IE8は、この目的で remainingSpace
プロパティを実装します。
alert(window.localStorage.remainingSpace); // should return 5000000 when empty
残念ながら、これは他のブラウザでは利用できないようです。しかし、それらが同様のものを実装しているかどうかはわかりません。
以下の行を使用して、この値を正確に計算できます。 こちらはjsfiddle
alert(1024 * 1024 * 5 - escape(encodeURIComponent(JSON.stringify(localStorage))).length);
今日(ストレージクォータを超えて)テストし、解決策を打ち出している間にこれに挑戦しました。 IMOは、制限が何であり、私たちがどこにいるのかを知ることは、クォータを超えて保存を続ける機能的な方法を実装するよりもはるかに価値がありません。
したがって、サイズの比較や容量のチェックを行うのではなく、クォータに達したときに対応し、現在のストレージを3分の1減らしてから、保存を再開します。上記の削減に失敗した場合、保存を停止します。
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(){}
}
}
}
}
この関数はラッパーオブジェクト内に存在するため、public.setはそれ自体を呼び出すだけです。これで、ストレージを追加することができ、クォータが何であるか、またはどれだけ近いかを心配する必要はありません。単一のストアがクォータサイズの3分の1を超えている場合、この関数はカリングを停止して保存を終了します。その時点では、とにかくキャッシュしないでください。
ブラウザのテスト結果に追加するには:
Firefox i = 22。
Safari Mac上のバージョン5.0.4はハングしませんでした。 Chromeとしてのエラー。 i = 21。
Opera Webサイトはデータを保存したいが、十分なスペースがないことをユーザーに通知します。ユーザーは、要求を拒否したり、必要な量または他のいくつかの制限に制限を引き上げたり、無制限に設定したりできます。 opera:webstorageに移動して、このメッセージが表示されるかどうかを確認します。 i = 20。スローされるエラーはChromeと同じです。
IE9標準モード Chromeとしてのエラー。 i = 22。
IE8標準モードのIE9コンソールメッセージ「エラー:この操作を完了するのに十分なストレージがありません」。 i = 22
古いモードのIE9オブジェクトエラー。 i = 22。
IE8テストするコピーはありませんが、ローカルストレージはサポートされています(http://stackoverflow.com/questions/3452816/does-ie8-support-out-of-the-box-in -ローカルストレージ)
IE7以下ローカルストレージをサポートしていません。
これでブラウザをテストできます web storage support test
テストした Firefox 両方でAndroidタブレットとWindowsラップトップと Chromium Windowsでの結果:
Firefox(windows):
Firefox(Android):
クロム(ウィンドウ):
Googleの場合Chromeバージョン52.0.2743.116 m(64ビット)制限5101k
文字。これは、使用可能な最大数がバージョンによって変わる可能性があることを意味します。
コメントにこれを追加したい-十分な担当者がいない、ごめんなさい。
いくつかのperfテストを実行しました-JSON.stringify(localStorage).lengthが大規模なlocalStorage占有での高価な操作であることを期待しています。
http://jsperf.com/occupied-localstorage-json-stringify-length
それは確かにそうです-あなたが保存しているものを追跡するよりも約50倍高価であり、より充実したlocalStorageが取得することで悪化します。
LocalStorageに便利な一連の関数を作成しました* here *
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();
これは非常に高速ではないため、常に使用しないでください
これにより、Item-Nameはその長さと同じくらいのスペースを占有し、Item-Valueもまたその長さと同じスペースを占有することがわかりました。
私が得た最大ストレージ-すべて約5M:
コンソールの進行状況を確認するために、フィドルにコメントのないコードがいくつかあります。
作るのに時間がかかりました。これが役立つことを願っています☺
ストレージがいっぱいになったときにモジュールが何をするかを実際にシミュレートしてテストする必要があったため、i ^ 2の割合でその精度を失う受け入れられた答えではなく、ストレージがいっぱいになったときに厳密な精度を取得する必要がありました。
スクリプトは次のとおりです。メモリ上限に達すると常に10の精度を生成し、簡単に最適化できるにもかかわらずかなり高速になります。編集:スクリプトをより正確に正確に作成しました。
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)
}
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
}
これは誰かを助けるかもしれません。 In 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 にアクセスしてください。