web-dev-qa-db-fra.com

Accès à localStorage à partir d'un webWorker

Un WebWorker peut-il accéder au localStorage?

Sinon pourquoi pas? Est-ce problématique du point de vue de la sécurité?

56
ciochPep

Non, localStorage et sessionStorage ne sont pas définis dans un processus de travail Web.

Vous devez rappeler postMessage() au code d'origine du Worker et demander à ce code de stocker les données dans localStorage.

Fait intéressant, un webworker peut utiliser un appel AJAX pour envoyer/récupérer des informations vers/depuis un serveur, ce qui peut ouvrir des possibilités, selon ce que vous essayez de faire) faire.

62
Speednet

Les travailleurs du Web n'ont accès qu'aux éléments suivants:

  • XMLHttpRequest
  • Cache d'application
  • créer d'autres employés Web
  • objet navigateur
  • objet de localisation
  • méthode setTimeout
  • méthode clearTimeout
  • méthode setInterval
  • méthode clearInterval
  • méthode importScripts
  • JSON
  • Ouvrier

La fenêtre ou les objets parents ne sont pas accessibles à partir d'un travailleur Web, vous ne pouvez donc pas accéder au localStorage.

Pour communiquer entre la fenêtre et le workerglobalscope, vous pouvez utiliser la fonction postMessage() et l'événement onmessage.

Accéder au DOM et à la fenêtre ne serait pas sûr pour les threads, car le thread enfant aurait les mêmes privilèges que son parent.

92
filipemgs

Vous pouvez utiliser IndexedDB dans WebWorkers qui est un moyen de stocker des choses localement dans un magasin de valeurs clés. Ce n'est pas la même chose que localStorage, mais il a des cas d'utilisation similaires et peut contenir beaucoup de données. Nous utilisons IndexedDB dans WebWorkers dans mon travail.

MODIFICATION août 2019:

Il existe une API proposée qui pourrait être disponible dans le futur (bien qu'elle soit actuellement disponible en Chrome Canary avec le drapeau des fonctionnalités Web expérimentales activé). Il s'appelle KV Storage (KV est l'abréviation de Key Valeur). Il a une interface presque identique à l'API localStorage et viendra dans les modules JavaScript. Il est construit à partir de l'API indexeddb, mais a une API beaucoup plus simple. En regardant le Spec il apparaît ceci va également fonctionner dans WebWorkers. Pour des exemples d'utilisation, consultez la page github de la spécification. En voici un exemple:

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

Voici les tests réussis Chrome Canary:

enter image description here

Bien qu'il ne soit pas nécessaire d'utiliser l'api kv-storage, le code ci-dessous est le cadre de test utilisé pour le code ci-dessus:

// ./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