Bespin エディターと HTML5 の localStorage を使用してアプリを作成しています。すべてのファイルをローカルに保存し、文法を支援し、JSLint および CSS と HTML 用のその他のパーサーを使用してユーザーを支援します。
localStorage 制限がどれだけ使用されたか、実際にどれだけあるかを計算したいと思います。これは今日可能ですか?格納されているビットを単純に計算しないように考えていました。しかし、自分で測定できないものがあるかどうかはわかりません。
Bespin エディターと HTML5 の localStorage を使用してアプリを作成しています。すべてのファイルをローカルに保存し、文法を支援し、JSLint および CSS と HTML 用のその他のパーサーを使用してユーザーを支援します。
localStorage 制限がどれだけ使用されたか、実際にどれだけあるかを計算したいと思います。これは今日可能ですか?格納されているビットを単純に計算しないように考えていました。しかし、自分で測定できないものがあるかどうかはわかりません。
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");
そこから私はこの情報を得ました:
グーグルクローム
モジラ ファイアフォックス
サファリ
Internet Explorer、Edge (コミュニティ)
私の解決策
これまでのところ、私の解決策は、ユーザーが何かを保存するたびに余分な呼び出しを追加することです。例外がキャッチされた場合は、ストレージ容量が不足していることを伝えます。
編集:追加されたデータを削除
DATA
これが実際に機能するには、最初に設定されたアイテムを削除する必要があることを忘れていました. 上記の変更は、 removeItem()関数を使用して反映されます。
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 は単にそれ自体を呼び出します。これで、ストレージを追加できるようになりました。クォータがどれくらいか、どれだけ近いかを心配する必要はありません。1 つのストアがクォータ サイズの 1/3 を超えている場合、この関数はカリングを停止して保存を終了します。その時点で、とにかくキャッシュするべきではありませんよね?
ブラウザのテスト結果に追加するには:
Firefox i=22.
Mac のSafari バージョン 5.0.4 はハングしませんでした。Chrome としてのエラー。i=21。
Opera Web サイトはデータを保存したいが、十分なスペースがないことをユーザーに伝えます。ユーザーはリクエストを拒否するか、制限を必要な量または他のいくつかの制限まで引き上げるか、無制限に設定することができます。このメッセージが表示されるかどうかを確認するには、opera:webstorage にアクセスしてください。i=20。スローされるエラーは Chrome と同じです。
Chrome としてIE9 標準モード エラー。i=22。
IE8 標準モードの IE9 コンソール メッセージ「エラー: この操作を完了するのに十分なストレージがありません」。i=22
古いモードの IE9 オブジェクト エラー。i=22。
IE8 テスト用のコピーはありませんが、ローカル ストレージはサポートされています (http://stackoverflow.com/questions/3452816/does-ie8-support-out-of-the-box-in-localstorage)
IE7 以下 ローカル ストレージをサポートしていません。
このウェブストレージサポートテストでブラウザをテストできます
Android タブレットと Windows ラップトップの両方でFirefoxをテストし、Windows の結果だけでChromiumをテストしました。
###Google Chrome バージョン 52.0.2743.116 m (64 ビット) の更新では、5101k
文字数が少し低くなります。これは、使用可能な最大数がバージョンで変わる可能性があることを意味します。
これをコメントに追加できたらいいのにと思います-担当者が足りません、ごめんなさい。
いくつかのパフォーマンス テストを実行しました。JSON.stringify(localStorage).length は、localStorage の占有率が高い場合に高価な操作になることを期待しています。
http://jsperf.com/owned-localstorage-json-stringify-length
それは確かにそうです-保存しているものを追跡するよりも約50倍高価であり、localStorageが完全になるほど悪化します.
ストレージがいっぱいになったときにモジュールが何をするかを実際にシミュレートしてテストする必要があったため、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)
}
これは誰かを助けるかもしれません。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にアクセスしてください。