browser.storage

Descripción

Usa la API de chrome.storage para almacenar, recuperar y hacer un seguimiento de los cambios en los datos del usuario.

Permisos

storage

Para usar la API de Storage, declara el permiso "storage" en el manifiesto de la extensión. Por ejemplo:

{
  "name": "My extension",
  ...
  "permissions": [
    "storage"
  ],
  ...
}

Ejemplos

En los siguientes ejemplos, se muestran las áreas de almacenamiento local, sync y session:

Ejemplo (local)

await browser.storage.local.set({ key: value });
console.log("Value is set");
const result = await browser.storage.local.get(["key"]);
console.log("Value is " + result.key);

Ejemplo (sincronización)

await browser.storage.sync.set({ key: value });
console.log("Value is set");
const result = await browser.storage.sync.get(["key"]);
console.log("Value is " + result.key);

Ejemplo (sesión)

await browser.storage.session.set({ key: value });
console.log("Value is set");
const result = await browser.storage.session.get(["key"]);
console.log("Value is " + result.key);

Para ver otras demostraciones de la API de Storage, explora cualquiera de los siguientes ejemplos:

Conceptos y uso

La API de Storage proporciona una forma específica de la extensión para conservar los datos y el estado del usuario. Es similar a las APIs de almacenamiento de la plataforma web (IndexedDB y Storage), pero se diseñó para satisfacer las necesidades de almacenamiento de las extensiones. Estas son algunas de las funciones clave:

  • Todos los contextos de extensión, incluidos el service worker de la extensión y las secuencias de comandos de contenido, tienen acceso a la API de Storage.
  • Los valores serializables de JSON se almacenan como propiedades de objeto.
  • La API de Storage es asíncrona con operaciones de lectura y escritura masivas.
  • Incluso si el usuario borra la caché y el historial de navegación, los datos persisten.
  • La configuración almacenada persiste incluso cuando se usa el modo Incógnito dividido.
  • Incluye un área de almacenamiento administrada exclusiva de solo lectura para las políticas empresariales.

¿Las extensiones pueden usar las APIs de almacenamiento web?

Si bien las extensiones pueden usar la interfaz Storage (accesible desde window.localStorage) en algunos contextos (ventanas emergentes y otras páginas HTML), no lo recomendamos por los siguientes motivos:

  • Los service workers de extensiones no pueden usar la API de Web Storage.
  • Las secuencias de comandos de contenido comparten el almacenamiento con la página host.
  • Los datos guardados con la API de Web Storage se pierden cuando el usuario borra su historial de navegación.

Para mover datos de las APIs de almacenamiento web a las APIs de almacenamiento de extensiones desde un service worker, haz lo siguiente:

  1. Prepara una página HTML de documento fuera de pantalla y un archivo de secuencia de comandos. El archivo de secuencia de comandos debe contener una rutina de conversión y un controlador onMessage.
  2. En el service worker de la extensión, verifica browser.storage para ver tus datos.
  3. Si no se encuentran tus datos, llama a createDocument().
  4. Después de que se resuelva la promesa que se muestra, llama a sendMessage() para iniciar la rutina de conversión.
  5. Dentro del controlador onMessage del documento fuera de pantalla, llama a la rutina de conversión.

También hay algunos matices en cuanto al funcionamiento de las APIs de almacenamiento web en las extensiones. Obtén más información en el artículo Almacenamiento y cookies.

Límites de almacenamiento y regulación

La API de Storage tiene limitaciones de uso:

  • Almacenar datos tiene costos de rendimiento, y la API incluye cuotas de almacenamiento. Planifica los datos que quieres almacenar para mantener el espacio de almacenamiento.
  • El almacenamiento puede tardar un tiempo en completarse. Estructura tu código para tener en cuenta ese tiempo.

Para obtener detalles sobre las limitaciones del área de almacenamiento y lo que sucede cuando se superan, consulta la información de cuotas de sync, local y session.

Áreas de almacenamiento

La API de Storage se divide en las siguientes áreas de almacenamiento:

Local

Los datos se almacenan de forma local y se borran cuando se quita la extensión. El límite de almacenamiento es de 10 MB (5 MB en Chrome 113 y versiones anteriores), pero se puede aumentar solicitando el permiso "unlimitedStorage". Te recomendamos que uses storage.local para almacenar cantidades de datos más grandes. De forma predeterminada, se expone a las secuencias de comandos de contenido, pero este comportamiento se puede cambiar llamando a browser.storage.local.setAccessLevel().

Administrado

El almacenamiento administrado es de solo lectura para las extensiones instaladas por políticas. Los administradores del sistema lo administran con un esquema definido por el desarrollador y políticas empresariales. Las políticas son similares a las opciones, pero las configura un administrador del sistema, en lugar del usuario. Esto permite que la extensión se preconfigure para todos los usuarios de una organización.

De forma predeterminada, storage.managed se expone a las secuencias de comandos de contenido, pero este comportamiento se puede cambiar llamando a browser.storage.managed.setAccessLevel(). Para obtener información sobre las políticas, consulta la documentación para administradores. Para obtener más información sobre el área de almacenamiento managed, consulta Manifiesto para áreas de almacenamiento.

Sesión

El almacenamiento de sesión conserva los datos en la memoria mientras se carga una extensión. El almacenamiento se borra si la extensión se inhabilita, se vuelve a cargar, se actualiza y cuando se reinicia el navegador. De forma predeterminada, no se expone a las secuencias de comandos de contenido, pero este comportamiento se puede cambiar llamando a browser.storage.session.setAccessLevel(). El límite de almacenamiento es de 10 MB (1 MB en Chrome 111 y versiones anteriores).

La interfaz storage.session es una de las varias que recomendamos para los service workers.

Sincronizar

Si el usuario habilita la sincronización, los datos se sincronizarán con todos los navegadores Chrome a los que haya accedido. Si se inhabilita, se comporta como storage.local. Chrome almacena los datos de forma local cuando el navegador está sin conexión y reanuda la sincronización cuando vuelve a estar en línea. La limitación de cuota es de aproximadamente 100 KB, 8 KB por elemento.

Te recomendamos que uses storage.sync para conservar la configuración del usuario en los navegadores sincronizados. Si trabajas con datos sensibles de los usuarios, usa storage.session en su lugar. De forma predeterminada, storage.sync se expone a las secuencias de comandos de contenido, pero este comportamiento se puede cambiar llamando a browser.storage.sync.setAccessLevel().

Métodos y eventos

Todas las áreas de almacenamiento implementan la interfaz StorageArea.

get()

El método get() te permite leer una o más claves de un StorageArea.

getBytesInUse()

El método getBytesInUse() te permite ver la cuota que usa un StorageArea.

getKeys()

El método getKeys() te permite obtener todas las claves almacenadas en un StorageArea.

remove()

El método remove() te permite quitar un elemento de un StorageArea.

set()

El método set() te permite establecer un elemento en un StorageArea.

setAccessLevel()

El método setAccessLevel() te permite controlar el acceso a un StorageArea.

clear()

El método clear() te permite borrar todos los datos de un StorageArea.

onChanged

El evento onChanged te permite supervisar los cambios en un StorageArea.

Casos de uso

En las siguientes secciones, se muestran casos de uso comunes de la API de Storage.

Cómo responder a las actualizaciones de almacenamiento

Para hacer un seguimiento de los cambios realizados en el almacenamiento, agrega un objeto de escucha a su evento onChanged. Cuando se produce un cambio en el almacenamiento, se activa ese evento. El código de muestra escucha estos cambios:

background.js:

browser.storage.onChanged.addListener((changes, namespace) => {
  for (let [key, { oldValue, newValue }] of Object.entries(changes)) {
    console.log(
      `Storage key "${key}" in namespace "${namespace}" changed.`,
      `Old value was "${oldValue}", new value is "${newValue}".`
    );
  }
});

Podemos llevar esta idea aún más lejos. En este ejemplo, tenemos una página de opciones que permite al usuario activar o desactivar un "modo de depuración" (la implementación no se muestra aquí). La página de opciones guarda de inmediato la nueva configuración en storage.sync, y el service worker usa storage.onChanged para aplicar el parámetro de configuración lo antes posible.

options.html:

<!-- type="module" allows you to use top level await -->
<script defer src="options.js" type="module"></script>
<form id="optionsForm">
  <label for="debug">
    <input type="checkbox" name="debug" id="debug">
    Enable debug mode
  </label>
</form>

options.js:

// In-page cache of the user's options
const options = {};
const optionsForm = document.getElementById("optionsForm");

// Immediately persist options changes
optionsForm.debug.addEventListener("change", (event) => {
  options.debug = event.target.checked;
  browser.storage.sync.set({ options });
});

// Initialize the form with the user's option settings
const data = await browser.storage.sync.get("options");
Object.assign(options, data.options);
optionsForm.debug.checked = Boolean(options.debug);

background.js:

function setDebugMode() { /* ... */ }

// Watch for changes to the user's options & apply them
browser.storage.onChanged.addListener((changes, area) => {
  if (area === 'sync' && changes.options?.newValue) {
    const debugMode = Boolean(changes.options.newValue.debug);
    console.log('enable debug mode?', debugMode);
    setDebugMode(debugMode);
  }
});

Carga previa asíncrona desde el almacenamiento

Debido a que los service workers no se ejecutan todo el tiempo, las extensiones de Manifest V3 a veces necesitan cargar datos de forma asíncrona desde el almacenamiento antes de ejecutar sus controladores de eventos. Para ello, el siguiente fragmento usa un controlador de eventos action.onClicked asíncrono que espera a que se complete la variable global storageCache antes de ejecutar su lógica.

background.js:

// Where we will expose all the data we retrieve from storage.sync.
const storageCache = { count: 0 };
// Asynchronously retrieve data from storage.sync, then cache it.
const initStorageCache = browser.storage.sync.get().then((items) => {
  // Copy the data retrieved from storage into storageCache.
  Object.assign(storageCache, items);
});

browser.action.onClicked.addListener(async (tab) => {
  try {
    await initStorageCache;
  } catch (e) {
    // Handle error that occurred during storage initialization.
  }

  // Normal action handler logic.
  storageCache.count++;
  storageCache.lastTabId = tab.id;
  browser.storage.sync.set(storageCache);
});

Herramientas para desarrolladores

Puedes ver y editar los datos almacenados con la API en las Herramientas para desarrolladores. Para obtener más información, consulta la página Cómo ver y editar el almacenamiento de extensiones en la documentación de las Herramientas para desarrolladores.

Tipos

AccessLevel

Chrome 102 y versiones posteriores browser.* desde Chrome 148

Es el nivel de acceso del área de almacenamiento.

Enum

"TRUSTED_CONTEXTS"
Especifica los contextos que se originan en la extensión.

"TRUSTED_AND_UNTRUSTED_CONTEXTS"
Especifica los contextos que se originan fuera de la extensión.

StorageChange

Propiedades

  • newValue

    any optional

    Es el valor nuevo del elemento, si hay uno.

  • oldValue

    any optional

    Es el valor anterior del elemento, si lo hubiera.

Propiedades

local

Los elementos del área de almacenamiento local son locales para cada máquina.

Tipo

StorageArea y objeto

Propiedades

  • QUOTA_BYTES

    10485760

    Es la cantidad máxima (en bytes) de datos que se pueden almacenar en el almacenamiento local, según la conversión a cadena JSON de cada valor más la longitud de cada clave. Este valor se ignorará si la extensión tiene el permiso unlimitedStorage. Las actualizaciones que provocarían que se supere este límite fallan de inmediato y establecen runtime.lastError cuando se usa una devolución de llamada, o una promesa rechazada si se usa async/await.

managed

Los elementos del área de almacenamiento managed se establecen mediante una política empresarial que configura el administrador del dominio y son de solo lectura para la extensión. Si se intenta modificar este espacio de nombres, se produce un error. Para obtener información sobre cómo configurar una política, consulta Manifiesto para áreas de almacenamiento.

session

Chrome 102 y versiones posteriores browser.* desde Chrome 148 MV3 y versiones posteriores

Los elementos del área de almacenamiento session se almacenan en la memoria y no se conservarán en el disco.

Tipo

StorageArea y objeto

Propiedades

  • QUOTA_BYTES

    10485760

    Es la cantidad máxima (en bytes) de datos que se pueden almacenar en la memoria, según se mide estimando el uso de memoria asignada de forma dinámica de cada valor y clave. Las actualizaciones que harían que se supere este límite fallan de inmediato y establecen runtime.lastError cuando se usa una devolución de llamada o cuando se rechaza una promesa.

sync

Los elementos del área de almacenamiento sync se sincronizan con la Sincronización de Chrome.

Tipo

StorageArea y objeto

Propiedades

  • MAX_ITEMS

    512

    Es la cantidad máxima de elementos que se pueden almacenar en el almacenamiento de sincronización. Las actualizaciones que provoquen que se supere este límite fallarán de inmediato y establecerán runtime.lastError cuando se use una devolución de llamada o cuando se rechace una promesa.

  • MAX_SUSTAINED_WRITE_OPERATIONS_PER_MINUTE

    1000000

    Obsoleto

    La API de storage.sync ya no tiene una cuota de operaciones de escritura sostenida.

  • MAX_WRITE_OPERATIONS_PER_HOUR

    1800

    Es la cantidad máxima de operaciones set, remove o clear que se pueden realizar cada hora. Esto es 1 cada 2 segundos, un límite inferior al límite de escrituras por minuto más alto a corto plazo.

    Las actualizaciones que harían que se supere este límite fallan de inmediato y establecen runtime.lastError cuando se usa una devolución de llamada o cuando se rechaza una promesa.

  • MAX_WRITE_OPERATIONS_PER_MINUTE

    120

    Es la cantidad máxima de operaciones set, remove o clear que se pueden realizar por minuto. Este límite es de 2 por segundo, lo que proporciona una mayor capacidad de procesamiento que las escrituras por hora durante un período más corto.

    Las actualizaciones que harían que se supere este límite fallan de inmediato y establecen runtime.lastError cuando se usa una devolución de llamada o cuando se rechaza una promesa.

  • QUOTA_BYTES

    102400

    Es la cantidad total máxima (en bytes) de datos que se pueden almacenar en el almacenamiento de sincronización, según se mide por la cadena JSON de cada valor más la longitud de cada clave. Las actualizaciones que harían que se supere este límite fallan de inmediato y establecen runtime.lastError cuando se usa una devolución de llamada o cuando se rechaza una promesa.

  • QUOTA_BYTES_PER_ITEM

    8192

    Es el tamaño máximo (en bytes) de cada elemento individual en el almacenamiento de sincronización, medido por la cadena JSON de su valor más la longitud de su clave. Las actualizaciones que contengan elementos que superen este límite fallarán de inmediato y establecerán runtime.lastError cuando se use una devolución de llamada o cuando se rechace una promesa.

Eventos

onChanged

browser.storage.onChanged.addListener(
  callback: function,
)

Se activa cuando cambian uno o más elementos.

Parámetros

  • callback

    función

    El parámetro callback se ve de la siguiente manera:

    (changes: object, areaName: string) => void

    • Cambios

      objeto

    • areaName

      string