Open4

Chrome 拡張機能 chrome.storage

ひげひげ

データの永続化

Chrome拡張機能を作るとき、Storage API という専用の機能が提供されています。このStorage API を経由してデータの読み書きを行います。Storage API の特徴として以下のようなものが挙げられる

  • サービスワーカーやコンテンツスクリプトからStorage APIにアクセスすることができる
  • キーバリューで保存される
  • 非同期で行うことができる
  • ユーザーがキャッシュと閲覧履歴を削除してもデータが保持される
  • ブラウザのsplit シークレットモードを利用している際でも保存しているデータは利用できる

データの保存方法は主に3つ

chrome.storage.保存方法.モード

で使い分けていきます。

chrome.storage.local

このAPIを使ってデータを保存するとき、手持ちのパソコン内にデータが保存され、拡張機能が削除されるときに一緒に保存したデータも削除されます。デフォルトでは約10MB保存することができ、パーミッションにunlimitedStorageを追加するとさらに大きいデータを保存できます。大抵の場合はこのオブジェクトでデータを保存します。ちなみにlocalと聞くとlocalStorageを連想される方がいるかもしれません。しかしこれらは異なるストレージなので注意してください。どちらも手元の端末内(ローカル)に保存される点では一致していますが後述するように機能は全然違います。

chrome.storage.sync
このAPIを使ってデータを保存すると、Googleのデータサーバーにデータが保存されます。保存可能なサイズはたった合計100KBで、一つのitemにつき8KBしか保存できません。しかしこのAPIの特徴は同期してあるGoogleアカウントとデータが共有できることです。設定などを共有する時に使うといいでしょう

先ほど2つ紹介したAPIは便利そうではありますが、一つ欠点があります。それは、保存されたデータが暗号化されていないということです。生データを保存することになるので、この2つのストレージに個人情報など漏れてはいけないデータを保存してはいけません。そういったデータは storage.sessionに保存するといいです

storage.session
このAPIを使ってデータを保存した場合、メモリ上に保存されます。ブラウザセッションが続く限りデータがメモリ上に残り続けます。デフォルト設定では、コンテントスクリプトでアクセスすることはできませんが、設定を変更することでアクセスすることもできます。セッションが終了するとデータが消えてしまうため、永続的なデータを保存することに向いていない。具体的にはわかりません。

ひげひげ

べからず集

localStorage は使わない方がいい

Web開発の経験がある人はブラウザで情報を保存する方法の1つとしてlocalStorageというのを聞いたことがあると思います。この方法で情報を保存するのはセキュリティ的によくありません。また、公式からも拡張機能開発でlocalStorageを使うことは非推奨とされています。その理由として以下のものが挙げられます。

  • サービスワーカーからlocalStorageにアクセスできない
  • コンテンツスクリプト経由で接続先のサイトがデータにアクセスできてしまう
  • ユーザーがブラウザを操作してlocalStorage上のデータを削除してしまう可能性がある
  • 同期的でしか保存できない
  • String型しか保存できない

よって拡張機能開発でデータを永続化させたい場合は chrome.storageを使うのが一択です。

https://blossomsarchive.com/blog/post-2110/
https://techracho.bpsinc.jp/hachi8833/2019_10_09/80851

window 直下にグローバル変数を生やすべからず

? serviceworkerでアクセスできるwindowと、content scriptでアクセスできるwindowは違う。service worker で定義したwindow直下のグローバル変数にcontent scriptでアクセスできるのか?仮にできたとしても共有するデータはchrome.storageに統一しておいた方が迷わなくて済む。

ひげひげ

get で存在しないキーにアクセスしてもエラーがでない

エラーが出なくて思いもしない挙動になるから、インストール時に初期データを入れた方がいい。

setのときは
chrome.storage.local.set( obj, function() {
if(chrome.runtime.lastError) {
console.error(
"Error setting " + key + " to " + JSON.stringify(val) +
": " + chrome.runtime.lastError.message
);
}
});
的なのがあるから、getでもあるのかなあ

ひげひげ

保存したデータの一覧を見る

サービスワーカーのdevtoolを開き、コンソールパネルで次のコードを実行する

console
// storage.syncの場合
chrome.storage.sync.get(null, ((data) => {console.log(data)}));
// storage.localの場合
chrome.storage.local.get(null, ((data) => {console.log(data)}));

データをすべて削除

// storage.syncの場合
chrome.storage.sync.clear();
// storage.localの場合
chrome.storage.local.clear();