Javascript 从 webWorker 访问 localStorage

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6179159/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 20:35:49  来源:igfitidea点击:

Accessing localStorage from a webWorker

javascripthtmllocal-storageweb-worker

提问by ciochPep

Can a WebWorker access the localStorage?

WebWorker 可以访问 localStorage 吗?

If not why not? Is it problematic from a security stand point?

如果不是为什么不呢?从安全的角度来看有问题吗?

回答by filipemgs

Web workers only have access to the following:

网络工作者只能访问以下内容:

The window or parent objects are not accessible from a Web worker therefore you can't access the localStorage.

Web 工作者无法访问窗口或父对象,因此您无法访问localStorage.

To communicate between window and the workerglobalscopeyou may use postMessage()function and onmessageevent.

要在窗口和窗口之间进行通信,workerglobalscope您可以使用postMessage()函数和onmessage事件。

Accessing the DOM and window would not be thread safe, since the child thread would have the same privileges as its parent.

访问 DOM 和窗口不是线程安全的,因为子线程与其父线程具有相同的权限。

回答by Speednet

No, localStorage and sessionStorage are both undefined in a webworker process.

不,localStorage 和 sessionStorage 在 webworker 进程中都未定义。

You would have to call postMessage()back to the Worker's originating code, and have that code store the data in localStorage.

您必须postMessage()回调 Worker 的原始代码,并让该代码将数据存储在 localStorage 中。

Interestingly, a webworker canuse an AJAX call to send/retrieve info to/from a server, so that may open possibilities, depending on what you're trying to do.

有趣的是,网络工作者可以使用 AJAX 调用向/从服务器发送/检索信息,因此这可能会打开各种可能性,具体取决于您尝试执行的操作。

回答by John

You can use IndexedDBin WebWorkerswhich is a way to store things locally in a key value store. It is not the same as localStorage, but it has similar use cases and can hold quite a lot of data. We use IndexedDB in WebWorkers at my work.

您可以在WebWorkers中使用IndexedDB,这是一种将内容本地存储在键值存储中的方法。它与 localStorage 不同,但它具有相似的用例并且可以保存相当多的数据。在我的工作中,我们在 WebWorkers 中使用 IndexedDB。

April 21, 2020 EDIT:

2020 年 4 月 21 日编辑:

The below edit for August 2019 no longer applies, it included information on the KV storage api which was an API that mirrored the localStorage API that was async and meant to be built on top of the Indexeddb API, as pointed out by @hoogw the KV Storage API is not currently being worked on to quote the KV storage spec:

2019 年 8 月的以下编辑不再适用,它包含有关 KV 存储 API 的信息,该 API 反映了异步的 localStorage API,旨在构建在 Indexeddb API 之上,正如@hoogw KV 所指出的存储 API 目前尚未用于引用KV 存储规范

Work on this [KV strorage] specification is currently suspended, as no browser teams (including the Chromium project, which originated the proposal) are currently indicating interest in implementing it.

此 [KV 存储] 规范的工作目前已暂停,因为目前没有浏览器团队(包括提出该提案的 Chromium 项目)表示有兴趣实施它。

August 2019 EDIT:

2019 年 8 月编辑:

There is a proposed API that might be out sometime in the future (although it's currently available in Chrome Canary with the experimental web features flag turned on). It's called KV Storage (KV is short for Key Value). It has an almost identical interface to the localStorage API and will come in JavaScript modules. It is built off of the indexeddb API, but has a much simpler API. Looking at the Specit appears this is going to work in WebWorkers as well. For examples how to use it see the github pageof the spec. Here is one such example:

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");
});

Here's the tests passing in Chrome Canary:

enter image description here

Although not necessary to use the kv-storage api the below code is the testing framework used for the above code:

// ./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() 
      } 
    }
  });
} 

有一个提议的 API 可能会在未来的某个时候推出(尽管它目前在 Chrome Canary 中可用,并打开了实验性网络功能标志)。它被称为 KV 存储(KV 是 Key Value 的缩写)。它具有与 localStorage API 几乎相同的接口,并且将出现在 JavaScript 模块中。它是基于 indexeddb API 构建的,但具有更简单的 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 中通过的测试:

在此处输入图片说明

虽然没有必要使用 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() 
      } 
    }
  });
} 

回答by hoogw

kvStorageis a good alternative, however,

kvStorage是一个不错的选择,但是,

Dec, 2019. kvStorage currently is NOT, and will NOT be supported in chrome in future as well.

2019 年 12 月。 kvStorage 目前不支持,将来也不支持 chrome。

Work on this specification is currently suspended, as no browser teams (including the Chromium project, which originated the proposal) are currently indicating interest in implementing it.

该规范的工作目前已暂停,因为目前没有浏览器团队(包括提出该提案的 Chromium 项目)表示有兴趣实施它。