Javascriptでブラウザにデータを格納

Javascriptでブラウザにデータ(文字列)を保存する。

最近使ったのでメモを残しておく。

データの格納手段

ブラウザへの保存といえば、Cookie(クッキー、cookie)も思いつくがそれよりもデータの格納に適したlocalStorageを使う。 cookieだと通信時に毎回通信に付加するので、クライアント側でしか使わない値なら無駄になる。

もう一つ似たものにsessionStorageもあるが、こっちはブラウザが閉じる(セッションが終了する)と消去されるもの。センシティブな情報を扱うときに適している。

手動以外で消えないようにするには、localStorageを使うのが最適。ユーザーのブラウザ設定によっては保存できない場合もある。保存できない場合は機能の一部が制限されることを表示などするといい。 localStorageが使えるかの検知方法はMDNに載っている:Web Storage API の使用 - Web API | MDN。下にも載せておく。

localStorageはオリジン(スキーマ://ホスト名:ポート番号)が同じ限りは共有される。

localStorageで実装

とてもシンプルだが、一応載せておく。検出のコードも載せておくが、MDNより古い場合もあるので注意(2021/02現在)。

// 検出用コード(MDNより)
function storageAvailable(type) {
    var storage;
    try {
        storage = window[type];
        var x = '__storage_test__';
        storage.setItem(x, x);
        storage.removeItem(x);
        return true;
    }
    catch(e) {
        return e instanceof DOMException && (
            // everything except Firefox
            e.code === 22 ||
            // Firefox
            e.code === 1014 ||
            // test name field too, because code might not be present
            // everything except Firefox
            e.name === 'QuotaExceededError' ||
            // Firefox
            e.name === 'NS_ERROR_DOM_QUOTA_REACHED') &&
            // acknowledge QuotaExceededError only if there's something already stored
            (storage && storage.length !== 0);
    }
}

function saveText() {
    // jQueryで要素とその中身を取得している。
    const text = $("#md > textarea").val();
    localStorage.setItem("text", text);
    console.log("localStorageに保存")
}

function loadText() {
    const loaded = localStorage.getItem("text");
    if (loaded !== null) {
        console.log("localStorageから取得:", loaded);
    } else {
        console.log("localStorageに対応するデータなし");
    }
}

localStorage利用の前に、storageAvailable('localStorage')を実行してtrueが返ってくるかチェックしておけばいい。

複雑なデータを格納するとき

localStorageは基本的には文字列だけ格納するのがいいと思うので、複雑なオブジェクトを格納したいときは、JSON.stringify()JSON.parse()を使ってオブジェクトを文字列にしたり、文字列からオブジェクトに戻したりすればいい。

var someObj = {
    id: '978-43094xxxxx',
    title: 'Hi!',
    pages: 122,
    price: 580,
    description: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.',
};
localStorage.setItem('abook', JSON.stringify(someObj));
console.log('保存完了')

// getItem()したらJSON.parse()を行ってオブジェクトに戻す。
var loaded = JSON.parse(localStorage.getItem('abook'));
console.log('読み込み完了:', loaded);
// オブジェクトであることを確認。
console.log('id:', loaded.id)

JSON.stringify()しないで保存したときは、保存データを取り出してもうまく扱えないようなので、文字列に変換してから保存するようにしよう。

おわり

Javascriptの内部で利用するデータの保存なら自由に使っていいと思うが、ユーザーが自分の意思でデータを保存したいときにlocalStorageを利用するなら、ケースによるが、データの上書きなどに注意する必要があると思う。

ブラウザによるが、localStorageに格納できるデータサイズは4MBを超えるなら他の方法も検討した方がいいかと思った。文字列だけならあまり問題はない範囲だが。ちなみにcookieは4KBともっと小さい。

今回はエラー処理についてはあまり考えていなかったが、検出コードを見た感じでは、容量を超えたりする場合もあるようなので、その辺のエラー処理は必要なんじゃないかと思う。追記で書くかも。

以上です。


Javascript関連書広告

JavaScript逆引きレシピ 第2版
Amazonで山田 祥寛のJavaScript逆引きレシピ 第2版。アマゾンならポイント還元本が多数。山田 祥寛作品ほか、お急ぎ便対象商品は当日お届けも可能。またJavaScript逆引きレシピ 第2版もアマゾン配送商品なら通常配送無料。
タイトルとURLをコピーしました