Accediendo a localStorage desde un webWorker

Resuelto ciochPep asked hace 13 años • 5 respuestas

¿Puede un WebWorker acceder al almacenamiento local?

¿Si no, porque no? ¿Es problemático desde el punto de vista de la seguridad?

ciochPep avatar May 31 '11 00:05 ciochPep
Aceptado

Los trabajadores web solo tienen acceso a lo siguiente:

  • XMLHttpRequest
  • Caché de aplicaciones
  • Crear otros trabajadores web
  • navigatorobjeto
  • locationobjeto
  • setTimeoutmétodo
  • clearTimeoutmétodo
  • setIntervalmétodo
  • clearIntervalmétodo
  • Performanceobjeto ( mark, measure, nowmétodos: caniuse?)
  • IndexedDBAPI (ver: caniuse?)
  • importScriptsmétodo
  • JSON
  • Worker

La ventana o los objetos principales no son accesibles desde un trabajador web, por lo tanto, no se puede acceder al archivo localStorage.

Para comunicarse entre la ventana y workerglobalscopepuede utilizar postMessage()función y onmessageevento.

Acceder al DOM y a la ventana no sería seguro para subprocesos, ya que el subproceso secundario tendría los mismos privilegios que su padre.

filipe avatar May 30 '2011 18:05 filipe

No, localStorage y sessionStorage no están definidos en un proceso de trabajo web.

Tendría que postMessage()volver a llamar al código de origen del Trabajador y hacer que ese código almacene los datos en localStorage.

Curiosamente, un trabajador web puede usar una llamada AJAX para enviar/recuperar información hacia/desde un servidor, lo que puede abrir posibilidades, dependiendo de lo que esté intentando hacer.

Speednet avatar May 30 '2011 18:05 Speednet

Puede utilizar IndexedDB en WebWorkers , que es una forma de almacenar cosas localmente en un almacén de valores clave. No es lo mismo que localStorage, pero tiene casos de uso similares y puede contener una gran cantidad de datos. Usamos IndexedDB en WebWorkers en mi trabajo.

9 de abril de 2021 EDITAR:

Para una biblioteca mínima que usa indexeddb refleja la API de almacenamiento local pero usa API asíncronas en lugar de sincronizadas, puede usar idb-keyvalla que se encuentra aquí . Al escribir grandes cantidades de datos, es mejor usar una API asíncrona como la anterior en JS, porque le permite no bloquear el hilo.

21 de abril de 2020 EDITAR:

La siguiente edición de agosto de 2019 ya no se aplica, incluía información sobre la API de almacenamiento de KV, que era una API que reflejaba la API de almacenamiento local que era asíncrona y estaba destinada a construirse sobre la API Indexeddb, como lo señaló @hoogw the KV. Actualmente no se está trabajando en la API de almacenamiento para citar la especificación de almacenamiento de KV :

El trabajo en esta especificación [KV strorage] está actualmente suspendido, ya que ningún equipo de navegadores (incluido el proyecto Chromium, que originó la propuesta) muestra interés en implementarla.

**EDICIÓN de agosto de 2019:**

Hay una API propuesta que podría estar disponible en algún momento en el futuro (aunque actualmente está disponible en Chrome Canary con el indicador de funciones web experimentales activado). Se llama KV Storage (KV es la abreviatura de Key Value). Tiene una interfaz casi idéntica a la API localStorage y vendrá en módulos JavaScript. Está construido a partir de la API indexeddb, pero tiene una API mucho más simple. Al observar las especificaciones , parece que esto también funcionará en WebWorkers. Para ver ejemplos de cómo usarlo, consulte la página de github de la especificación. He aquí uno de esos ejemplos:

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

Aquí están las pruebas que se pasan en Chrome Canary:

ingrese la descripción de la imagen aquí

Aunque no es necesario utilizar la API de kv-storage, el siguiente código es el marco de prueba utilizado para el código anterior:

// ./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() 
      } 
    }
  });
} 
John avatar Dec 18 '2015 19:12 John

kvStorage es una buena alternativa, sin embargo,

Diciembre de 2019. Actualmente, kvStorage NO es compatible con Chrome y tampoco lo será en el futuro.

El trabajo en esta especificación está actualmente suspendido, ya que ningún equipo de navegadores (incluido el proyecto Chromium, que originó la propuesta) muestra interés en implementarla.

hoogw avatar Dec 31 '2019 19:12 hoogw