Accessing localStorage from a webWorker
Asked Answered
C

5

76

Can a WebWorker access the localStorage?

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

Caldwell answered 30/5, 2011 at 17:29 Comment(1)
F
78

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

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

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

Flawed answered 30/5, 2011 at 18:28 Comment(1)
most environments support webworker access to indexeddbVibrate
P
121

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.

To communicate between window and the workerglobalscope you may use postMessage() function and onmessage event.

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

Polygraph answered 30/5, 2011 at 18:52 Comment(5)
it can access indexedDB however.Edelsten
And thread-safety is not a concern for localStorage, as it already needs to provide synchronized access to accomodate multiple browser tabs accessing it at the same time. #22001612Lynnett
A web worker cannot always create other web workers (for example Chrome doesn't support this)... Check a question and answers about this here.Miun
currently indexedDB is not accessible in a web worker on SafariBlackboard
many years later, IndexedDB is avaiable in web worker on all browsers caniuse.com/mdn-api_indexeddb_worker_supportPeirsen
F
78

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

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

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

Flawed answered 30/5, 2011 at 18:28 Comment(1)
most environments support webworker access to indexeddbVibrate
D
40

You can use IndexedDB in WebWorkers which 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.

April 9th, 2021 EDIT:

For a minimal library that using indexeddb mirrors the local storage api but uses async rather than sync apis you could use idb-keyval which is located here. When writing large amounts of data it's better to use an async api like the above in JS, because it allows you to not block the thread.

April 21, 2020 EDIT:

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:

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.

**August 2019 EDIT:**

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 Spec it appears this is going to work in WebWorkers as well. For examples how to use it see the github page of 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() 
      } 
    }
  });
} 
Dabbs answered 18/12, 2015 at 19:38 Comment(3)
Can't see why this was down voted so I up voted it so it came back to zero. LocalStorage can't be used in a webworker and if one needs storage in the browser IndexedDB is the alternative which do work in a worker.Kazmirci
currently indexedDB is not accessible in a web worker on SafariBlackboard
Dec, 2019. kvStorage will not supported in chrome in future. This spec is suspending for no specified term.Byzantium
B
2

kvStorage is a good alternative, however,

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

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.

Byzantium answered 31/12, 2019 at 19:53 Comment(0)
L
2

Partytown can help here - https://github.com/builderio/partytown

With it, you can read/write main thread data from the worker thread, without having to build a bunch of postMessage protocols back and forth

Lichenin answered 15/2, 2022 at 18:26 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.