Can a WebWorker access the localStorage?
If not why not? Is it problematic from a security stand point?
Can a WebWorker access the localStorage?
If not why not? Is it problematic from a security stand point?
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.
Web workers only have access to the following:
XMLHttpRequest
navigator
objectlocation
objectsetTimeout
methodclearTimeout
methodsetInterval
methodclearInterval
methodimportScripts
methodJSON
Worker
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.
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.
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:
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()
}
}
});
}
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.