web-dev-qa-db-ja.com

webWorkerからlocalStorageにアクセスする

WebWorkerはlocalStorageにアクセスできますか?

そうでない場合はなぜですか?セキュリティの観点から問題がありますか?

56
ciochPep

いいえ、localStorageとsessionStorageは両方ともWebworkerプロセスで未定義です。

postMessage()をWorkerの元のコードにコールバックし、そのコードにlocalStorageにデータを保存させる必要があります。

興味深いことに、Webworker canを使用してAJAXを呼び出してサーバーに情報を送信したり、サーバーから情報を取得します。行う。

62
Speednet

Webワーカーは以下にのみアクセスできます。

  • XMLHttpRequest
  • アプリケーションキャッシュ
  • 他のウェブワーカーを作成する
  • ナビゲーターオブジェクト
  • ロケーションオブジェクト
  • setTimeoutメソッド
  • clearTimeoutメソッド
  • setIntervalメソッド
  • clearIntervalメソッド
  • importScriptsメソッド
  • JSON
  • ワーカー

ウィンドウまたは親オブジェクトはWebワーカーからアクセスできないため、localStorageにアクセスできません。

ウィンドウとworkerglobalscopeの間で通信するには、postMessage()関数とonmessageイベントを使用できます。

子スレッドは親と同じ特権を持つため、DOMとウィンドウへのアクセスはスレッドセーフではありません。

92
filipemgs

WebWorkersIndexedDB を使用できます。これは、キーバリューストアにローカルに保存する方法です。 localStorageとは異なりますが、同様の使用例があり、非常に多くのデータを保持できます。私の仕事では、WebWorkersでIndexedDBを使用しています。

2019年8月編集:

将来リリースされる可能性のある提案されたAPIがあります(現在、Chrome実験的なWeb機能フラグがオンのカナリアで利用可能です)。KVストレージと呼ばれます(KVはKeyの略です)値)。localStorage APIとほぼ同じインターフェースを持ち、JavaScriptモジュールで提供されます。indexeddbAPIから構築されていますが、はるかに単純なAPIを持っています。 Spec WebWorkersでも動作します。使用方法の例については、仕様の githubページ を参照してください。

import storage, { StorageArea } from "std:kv-storage";
import {test, assert} from "./florence-test";

test("kv-storage test",async () => {
  await storage.clear()
  await storage.set("mycat", "Tom");
  assert(await storage.get("mycat") === "Tom", "storage: mycat is Tom");

  const otherStorage = new StorageArea("unique string");
  await otherStorage.clear()
  assert(await otherStorage.get("mycat") === undefined, "otherStorage: mycat is undefined");
  await otherStorage.set("mycat", "Jerry");
  assert(await otherStorage.get("mycat") === "Jerry", "otherStorage: mycat is Jerry");
});

以下は、Chrome Canary:

enter image description here

Kv-storage apiを使用する必要はありませんが、以下のコードは上記のコードに使用されるテストフレームワークです。

// ./florence-test.js

// Ryan Florence's Basic Testing Framework modified to support async functions
// https://Twitter.com/ryanflorence/status/1162792430422200320
const lock = AsyncLock();

export async function test (name, fn) {
  // we have to lock, so that console.groups are grouped together when
  // async functions are used.
  for await (const _ of lock) {
    console.group(name);
    await fn();
    console.groupEnd(name);
  }
};

export function assert (cond, desc) {
  if (cond) {
    console.log("%c✔️", "font-size: 18px; color: green", desc);
  } else {
    console.assert(cond, desc);
  }
};

// https://codereview.stackexchange.com/questions/177935/asynclock-implementation-for-js
function AsyncLock() { 
  const p = () => new Promise(next => nextIter = next ); 
  var nextIter, next = p(); 
  const nextP = () => { const result = next; next = result.then(() => p() ); return result;} 
  nextIter(); 
  return Object.assign({}, { 
    async * [Symbol.asyncIterator] () {
      try { 
        yield nextP() 
      } finally {
      nextIter() 
      } 
    }
  });
} 
31
John