Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

Chromeエクステンションを作ろう:ストレージ編

More than 5 years have passed since last update.

説明で使用した拡張機能はこちらからインストールできます. 一人でも多くの方に利用いただければ幸いです.
ソースコードはこちらから閲覧できます.

ストレージとは

拡張機能で永続化したい情報を保存する仕組みです.
Chrome-Javascript-APIから次の3つのストレージエリアが提供されています.

  • sync
  • local
  • managed

ストレージ系のAPIは、すべてコールバック関数で処理結果を受け取ります.
UIをブロッキングしないための配慮なのでしょうが、使い勝手は良くありません.

保存処理の例
function saveChanges() {
    var theValue = textarea.value;
    chrome.storage.sync.set({'value': theValue}, function() {
        console.log('Settings saved');
    });
}

詳細は公式サイトを参照してください.

プラグインで実装したこと

  • チケット登録画面からデータ取得と保存
  • オプション画面からデータ取得と保存、削除。 ストレージ使用状況の取得。

マニフェストファイルの設定 (抜粋)

manifest.json
   ,"permissions": [
        "storage"
    ]

詳細は公式サイトを参照してください.

permissions

プラグインが必要とする権限です.
ストレージを利用する場合はstorageを指定します.

ストレージエリア

sync

Chromeにより同期されるストレージエリアです.
Chromeにログインした状態であれば、保存したデータは異なるデバイスにも自動的に同期されます.

とても魅力的な機能ですが、利用制限制限がかなり厳しいためプラグインでは利用していません.

local

ブラウザ内に閉じたストレージエリアです.
利用制限はありますが、syncほど厳しくはありません.

プラグインでは、localを利用しました.

managed

ドメイン管理者により設定され、拡張機能からは読取専用となるストレージエリアです.
といってもまったく調べていないため、これ以上の説明はできません.

利用制限

syncとlocalには、利用制限が設けられています.
後述するストレージエリアのメソッドを呼び出した際に利用制限に違反した場合は、runtime.lastErrorにエラー情報が設定されます.

制限項目 syncのしきい値 localのしきい値 意味合い
QUOTA_BYTES 102,400 5,242,880 拡張機能で保存できるバイト数の上限です
QUOTA_BYTES_PER_ITEM 8,192 - 1項目で保存できるバイト数の上限です
MAX_ITEMS 512 - 拡張機能で保存できる項目数の上限です
MAX_WRITE_OPERATIONS_PER_HOUR 1,800 - 1時間あたりの更新回数の上限です
MAX_WRITE_OPERATIONS_PER_MINUTE 120 - 1分間あたりの更新回数の上限です

バイト数は、キーと値をそれぞれJSON.stringifyして加算した値になります.
項目数は、トップレベルの項目数になります.

例えば下記のサンプルデータは、次のように計上されます.

  • 項目数=2
  • 全体のバイト数=48
  • 項目hogeのバイト数=20 ("hoge""col1":"value"のバイト数の和)
  • 項目fugaのバイト数=28 ("fuga""col1":10,"col2":falseのバイト数の和)
サンプルデータ
{
  hoge: {
    col1: 'value'
  },
  fuga: {
    col1: 10,
    col2: false
  }
}

ストレージエリアのメソッド

プラグインで利用したストレージ系のAPIを説明します.

公式サイト

get

ストレージエリアからデータを取得します.

  • 第1引数には、取得するデータのキー文字列などを指定します.
    • 省略する ... すべてのデータを取得します.
    • キー文字列 ... 指定したキーに対する項目を取得します.
    • キー文字列の配列 ... 指定したキーに対する項目をすべて取得します.
    • オブジェクト ... 指定したオブジェクトのキーに対する項目を取得します. キーが存在しない場合は指定したオブジェクトの値が初期値になります.
  • 第2引数には、取得したデータを処理するコールバック関数を指定します.
var defaults = {};
defaults.hoge = {
    col1: 'no data';
};

chrome.storage.local.get(defaults, function(items) {
    console.log(items.hoge.col1);
});

set

ストレージエリアにデータを永続化します.

  • 第1引数には、永続化するデータを指定します.
  • 第2引数には、コールバック関数を指定します.
var entity = {};
entity.hoge = {
    col1: 'new data';
};

chrome.storage.local.set(entity, function() {
    console.log('stored');
});

remove

ストレージエリアからデータを削除します.

  • 第1引数には、削除するデータのキー文字列などを指定します.
    • キー文字列 ... 指定したキーに対する項目を削除します.
    • キー文字列の配列 ... 指定したキーに対する項目をすべて削除します.
  • 第2引数には、コールバック関数を指定します.
var key = 'hoge';

chrome.storage.local.remove(key, function() {
    console.log('removed');
});

getBytesInUse

ストレージエリアへの登録バイト数を取得します.

  • 第1引数には、取得するデータのキー文字列などを指定します.
    • 省略する ... すべてのデータの合計バイト数を取得します.
    • キー文字列 ... 指定したキーに対する項目のバイト数を取得します.
    • キー文字列の配列 ... 指定したキーに対する項目の合計バイト数を取得します.
  • 第2引数には、取得したデータを処理するコールバック関数を指定します.
var defaults = {};
defaults.hoge = {
    col1: 'no data';
};

chrome.storage.local.get(defaults, function(bytesInUse) {
    console.log(bytesInUse);
});

tips

ストレージエリアを確認するスクリプト

バックグラウンドページやオプションページを実装済みであれば、次の手順で登録されたデータを確認できます.
コンテントスクリプトの対象Webページからは、chromeにアクセスできないため実行できません.

  1. バックグラウンドページやオプションページを表示
  2. デベロッパーツールを起動する
  3. コンソールで下記のスクリプトを実行する
chrome.storage.local.get(function(items) { console.log(items) })

ストレージエリアを枯渇させるスクリプト(バイト)

コンソールで下記のスクリプトを実行します.
appendDataSizeを適宜調整してください.

overflow-byte.js
storage = chrome.storage.local;
appendKeyPrefix = 'overflow-';
appendDataSize = 5000 * 1024 - 200;
storage.get(function(e) {
    keys = [];
    $.each(e, function(key, value) {
        if (key.startsWith(appendKeyPrefix)) {
            keys.push(key);
        }
    });
    storage.remove(keys, function() {
        entity = {};
        for (i = 0; i < 10000; i++) {
            key = appendKeyPrefix + i;
            value = '0'.repeat(512);
            entity[key] = value;
            if (JSON.stringify(entity).length > appendDataSize) {
                break;
            }
        }

        storage.set(entity, function() {
            storage.get(function(e) {
                console.log(e);
            });
        });
    });
});

ストレージエリアを枯渇させるスクリプト(項目数)

コンソールで下記のスクリプトを実行します.
appendKeyCountを適宜調整してください.

overflow-keys.js
storage = chrome.storage.sync;
appendKeyPrefix = 'overflow-';
appendKeyCount = 500;
storage.get(function(e) {
    keys = [];
    $.each(e, function(key, value) {
        if (key.startsWith(appendKeyPrefix)) {
            keys.push(key);
        }
    });
    storage.remove(keys, function() {
        keys = {};
        for (i = 0; i < appendKeyCount; i++) {
            keys[appendKeyPrefix + i] = {};
        }
        storage.set(keys, function() {
            storage.get(function(e) {
                console.log(e);
            });
        });
    });
});

説明で紹介したプラグインのソースコード

dhun
気づけば初老を超えました. 疲れがとれにくくなってきたけど、まだまだ現役プログラマーです ヽ(^。^)ノ
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away