Descripción
Usa la API de chrome.storage
para almacenar, recuperar y realizar un seguimiento de los cambios en los datos del usuario.
Permisos
storage
Descripción general
La API de Storage proporciona una forma específica de la extensión de 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. A continuación, se muestran algunas funciones clave:
- Todos los contextos de la extensión, incluidos el service worker de 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 masivas de lectura y escritura.
- Los datos se conservarán incluso si el usuario borra la caché y el historial de navegación.
- La configuración almacenada se conserva incluso cuando se usa el modo de navegación de incógnito dividido.
- Incluye un área de almacenamiento administrada exclusiva de solo lectura para las políticas empresariales.
Si bien las extensiones pueden usar la interfaz [Storage
][mdn-storage] (accesible desde window.localStorage
) en algunos contextos (ventanas emergentes y otras páginas HTML), no se recomienda por los siguientes motivos:
- El service worker de la extensión no puede acceder a
Storage
. - Las secuencias de comandos de contenido comparten el almacenamiento con la página de host.
- Los datos guardados con la interfaz de
Storage
se pierden cuando el usuario borra su historial de navegación.
Para transferir datos de las APIs de almacenamiento web a las APIs de almacenamiento de extensiones desde un service worker, haz lo siguiente:
- Crea un documento fuera de pantalla con una rutina de conversión y un controlador [
onMessage
][on-message]. - Agregar una rutina de conversión a un documento fuera de pantalla
- En el service worker de extensiones, busca los datos en
chrome.storage
. - Si no se encuentran tus datos, [crea][create-offscreen] un documento fuera de pantalla y llama a [
sendMessage()
][send-message] para iniciar la rutina de conversión. - Dentro del controlador
onMessage
del documento fuera de pantalla, llama a la rutina de conversión.
También hay algunos matices en el funcionamiento de las APIs de almacenamiento web en extensiones. Obtén más información en el [Almacenamiento y cookies][storage-and-cookies].
Áreas de almacenamiento
La API de Storage se divide en los siguientes cuatro buckets (“áreas de almacenamiento”):
storage.local
- Los datos se almacenan de forma local, y se borran cuando se quita la extensión. El límite de la cuota es de aproximadamente 10 MB, pero se puede aumentar mediante la solicitud del permiso
"unlimitedStorage"
. Considera usarlo para almacenar grandes cantidades de datos.
storage.sync
- Si la sincronización está habilitada, los datos se sincronizan con cualquier navegador Chrome en el que el usuario haya accedido. Si está inhabilitada, 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 está de nuevo en línea. El límite de la cuota es de aproximadamente 100 KB y 8 KB por elemento. Considera usarla para preservar la configuración del usuario en todos los navegadores sincronizados.
- storage.session
- Conserva datos en la memoria durante una sesión del navegador. De forma predeterminada, no está expuesto a secuencias de comandos de contenido, pero este comportamiento se puede cambiar si configuras
chrome.storage.session.setAccessLevel()
. El límite de cuota es de aproximadamente 10 MB. Te recomendamos usarlo para almacenar variables globales en las ejecuciones de los service workers.
- storage.managed
- Los administradores pueden usar un esquema y políticas empresariales para establecer la configuración de una extensión complementaria en un entorno administrado. Esta área de almacenamiento es de solo lectura.
Manifiesto
Para usar la API de Storage, declara el permiso "storage"
en la extensión
manifiesto. Por ejemplo:
{
"name": "My extension",
...
"permissions": [
"storage"
],
...
}
Uso
En los siguientes ejemplos, se muestran los atributos local
, sync
y
session
áreas de almacenamiento:
storage.local
chrome.storage.local.set({ key: value }).then(() => {
console.log("Value is set");
});
chrome.storage.local.get(["key"]).then((result) => {
console.log("Value currently is " + result.key);
});
storage.sync
chrome.storage.sync.set({ key: value }).then(() => {
console.log("Value is set");
});
chrome.storage.sync.get(["key"]).then((result) => {
console.log("Value currently is " + result.key);
});
storage.session
chrome.storage.session.set({ key: value }).then(() => {
console.log("Value was set");
});
chrome.storage.session.get(["key"]).then((result) => {
console.log("Value currently is " + result.key);
});
Para obtener más información sobre el área de almacenamiento de managed
, consulta el Manifiesto de las áreas de almacenamiento.
Límites de almacenamiento y regulación
No pienses en agregar a la API de Storage como si fuera un camión grande. Puedes aumentar almacenamiento como colocar algo en una tubería. Es posible que la tubería ya tenga material y que pueden llenarse. Siempre supón que hay una demora entre el momento en que agregas al almacenamiento y el momento en que se agrega se graban.
Para obtener detalles sobre las limitaciones del área de almacenamiento y lo que sucede cuando se superan, consulta la información sobre la cuota de sync
, local
y session
.
Casos de uso
En las siguientes secciones, se muestran casos de uso comunes para la API de Storage.
Respuesta síncrona a las actualizaciones de almacenamiento
Para realizar un seguimiento de los cambios realizados en el almacenamiento, puedes agregar un objeto de escucha a su evento onChanged
. Cuando se produce algún cambio en el almacenamiento, se activa ese evento. El código de muestra detecta estos cambios:
background.js:
chrome.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 inmediatamente la nueva configuración en storage.sync
, y el service worker usa storage.onChanged
para aplicar la 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;
chrome.storage.sync.set({ options });
});
// Initialize the form with the user's option settings
const data = await chrome.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
chrome.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
Dado que los service workers no siempre se ejecutan, las extensiones de Manifest V3 a veces necesitan
cargar datos de forma asíncrona desde el almacenamiento antes de que ejecuten sus controladores de eventos. Para ello, el
El siguiente fragmento usa un controlador del evento action.onClicked
asíncrono que espera el evento storageCache
.
global se propagará 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 = chrome.storage.sync.get().then((items) => {
// Copy the data retrieved from storage into storageCache.
Object.assign(storageCache, items);
});
chrome.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;
chrome.storage.sync.set(storageCache);
});
Ejemplos de extensiones
Para ver otras demostraciones de la API de Storage, explora cualquiera de los siguientes ejemplos:
Tipos
AccessLevel
El nivel de acceso del área de almacenamiento.
Enum
"TRUSTED_CONTEXTS"
Especifica contextos que se originan en la extensión.
"TRUSTED_AND_UNTRUSTED_CONTEXTS"
Especifica contextos que se originan fuera de la extensión.
StorageArea
Propiedades
-
onChanged
Evento<functionvoidvoid>
Chrome 73 y versiones posterioresSe activa cuando cambian uno o más elementos.
La función
onChanged.addListener
se ve de la siguiente manera:(callback: function) => {...}
-
callback
función
El parámetro
callback
se ve de la siguiente manera:(changes: object) => void
-
Cambios
objeto
-
-
-
borrar
void
PromesaQuita todos los elementos del almacenamiento.
La función
clear
se ve de la siguiente manera:(callback?: function) => {...}
-
callback
función opcional
El parámetro
callback
se ve de la siguiente manera:() => void
-
muestra
Promesa<void>
Chrome 88 y versiones posterioresLas promesas solo son compatibles con Manifest V3 y versiones posteriores; otras plataformas deben usar devoluciones de llamada.
-
-
get
void
PromesaObtiene uno o más elementos del almacenamiento.
La función
get
se ve de la siguiente manera:(keys?: string | string[] | object, callback?: function) => {...}
-
claves
string | string[] | objeto opcional
Una clave única para obtener, una lista de claves para obtener o un diccionario que especifica los valores predeterminados (consulta la descripción del objeto). Una lista o un objeto vacío devolverá un objeto de resultado vacío. Pasa
null
para obtener todo el contenido del almacenamiento. -
callback
función opcional
El parámetro
callback
se ve de la siguiente manera:(items: object) => void
-
elementos
objeto
Objeto con elementos en sus asignaciones de pares clave-valor.
-
-
muestra
Promise<object>
Chrome 88 y versiones posterioresLas promesas solo son compatibles con Manifest V3 y versiones posteriores; otras plataformas deben usar devoluciones de llamada.
-
-
getBytesInUse
void
PromesaObtiene la cantidad de espacio (en bytes) que usan uno o más elementos.
La función
getBytesInUse
se ve de la siguiente manera:(keys?: string | string[], callback?: function) => {...}
-
claves
string | string[] opcional
Una sola clave o lista de claves para obtener el uso total. Una lista vacía mostrará 0. Pasa
null
para obtener el uso total de todo el almacenamiento. -
callback
función opcional
El parámetro
callback
se ve de la siguiente manera:(bytesInUse: number) => void
-
bytesInUse
número
Cantidad de espacio que se utiliza en el almacenamiento, en bytes.
-
-
muestra
Promise<number>
Chrome 88 y versiones posterioresLas promesas solo son compatibles con Manifest V3 y versiones posteriores; otras plataformas deben usar devoluciones de llamada.
-
-
getKeys.
void
Promesa PendienteObtiene todas las claves del almacenamiento.
La función
getKeys
se ve de la siguiente manera:(callback?: function) => {...}
-
callback
función opcional
El parámetro
callback
se ve de la siguiente manera:(keys: string[]) => void
-
claves
string[]
Array con claves leídas desde el almacenamiento.
-
-
muestra
Promise<string[]>
Las promesas solo son compatibles con Manifest V3 y versiones posteriores; otras plataformas deben usar devoluciones de llamada.
-
-
quitar
void
PromesaQuita uno o más elementos del almacenamiento.
La función
remove
se ve de la siguiente manera:(keys: string | string[], callback?: function) => {...}
-
claves
string | cadena
Una sola clave o una lista de claves para los elementos que se quitarán.
-
callback
función opcional
El parámetro
callback
se ve de la siguiente manera:() => void
-
muestra
Promesa<void>
Chrome 88 y versiones posterioresLas promesas solo son compatibles con Manifest V3 y versiones posteriores; otras plataformas deben usar devoluciones de llamada.
-
-
set
void
PromesaConfigura varios elementos.
La función
set
se ve de la siguiente manera:(items: object, callback?: function) => {...}
-
elementos
objeto
Un objeto que le da a cada par clave-valor con el que se actualizará el almacenamiento. Los demás pares clave-valor almacenados en el almacenamiento no se verán afectados.
Los valores primitivos, como los números, se serializarán según lo previsto. Por lo general, los valores con un
typeof
"object"
y"function"
se serializan en{}
, a excepción deArray
(serializa como se espera),Date
yRegex
(serializan con su representaciónString
). -
callback
función opcional
El parámetro
callback
se ve de la siguiente manera:() => void
-
muestra
Promesa<void>
Chrome 88 y versiones posterioresLas promesas solo son compatibles con Manifest V3 y versiones posteriores; otras plataformas deben usar devoluciones de llamada.
-
-
setAccessLevel
void
Promesa Chrome 102 y versiones posteriores .Establece el nivel de acceso deseado para el área de almacenamiento. La configuración predeterminada serán solo contextos de confianza.
La función
setAccessLevel
se ve de la siguiente manera:(accessOptions: object, callback?: function) => {...}
-
accessOptions
objeto
-
accessLevel
El nivel de acceso del área de almacenamiento.
-
-
callback
función opcional
El parámetro
callback
se ve de la siguiente manera:() => void
-
muestra
Promesa<void>
Las promesas solo son compatibles con Manifest V3 y versiones posteriores; otras plataformas deben usar devoluciones de llamada.
-
StorageChange
Propiedades
-
newValue
Cualquier opcional
Es el valor nuevo del elemento, si existe uno nuevo.
-
oldValue
Cualquier opcional
El valor anterior del artículo, si existía uno anterior.
Propiedades
local
Los elementos en el área de almacenamiento de local
son locales para cada máquina.
Tipo
StorageArea y objeto
Propiedades
-
QUOTA_BYTES
10485760
La cantidad máxima (en bytes) de datos que se pueden almacenar en el almacenamiento local, según la medición de la stringificación JSON de cada valor más la longitud de cada clave. Se ignorará este valor si la extensión tiene el permiso
unlimitedStorage
. Las actualizaciones que podrían provocar que se supere este límite fallan inmediatamente y establecenruntime.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 de managed
son establecidos por una política empresarial configurada por el administrador de dominio y son de solo lectura para la extensión. Si intentas modificar este espacio de nombres se generará un error. Si quieres obtener información para configurar una política, consulta el Manifiesto de las áreas de almacenamiento.
Tipo
session
Los elementos del área de almacenamiento de session
se almacenan en la memoria y no se conservarán en el disco.
Tipo
StorageArea y objeto
Propiedades
-
QUOTA_BYTES
10485760
La cantidad máxima (en bytes) de datos que se pueden almacenar en la memoria, según se mide estimando el uso de memoria asignado de forma dinámica de cada valor y clave. Las actualizaciones que podrían provocar que se supere este límite fallan inmediatamente 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 de sync
se sincronizan con la Sincronización de Chrome.
Tipo
StorageArea y objeto
Propiedades
-
MAX_ITEMS
512
La cantidad máxima de elementos que se pueden almacenar en el almacenamiento sincronizado. Las actualizaciones que podrían provocar que se supere este límite fallarán de inmediato y configurarán
runtime.lastError
cuando se use una devolución de llamada o cuando se rechace una promesa. -
MAX_SUSTAINED_WRITE_OPERATIONS_PER_MINUTE
1,000,000
ObsoletoLa API de storage.sync ya no tiene una cuota de operaciones de escritura sostenidas.
-
MAX_WRITE_OPERATIONS_PER_HOUR
1,800
La cantidad máxima de operaciones
set
,remove
oclear
que se pueden realizar por hora. Esta cifra es de 1 cada 2 segundos, un límite más bajo que el límite más alto a corto plazo de operaciones de escritura por minuto.Las actualizaciones que podrían provocar que se supere este límite fallan inmediatamente y establecen
runtime.lastError
cuando se usa una devolución de llamada o cuando se rechaza una promesa. -
MAX_WRITE_OPERATIONS_PER_MINUTE
120
La cantidad máxima de operaciones
set
,remove
oclear
que se pueden realizar por minuto. Es de 2 por segundo, lo que proporciona una capacidad de procesamiento mayor que las escrituras por hora durante un período más corto.Las actualizaciones que podrían provocar que se supere este límite fallan inmediatamente y establecen
runtime.lastError
cuando se usa una devolución de llamada o cuando se rechaza una promesa. -
QUOTA_BYTES
102,400
La cantidad total máxima (en bytes) de datos que se pueden almacenar en el almacenamiento síncrono, según lo medido por la stringificación JSON de cada valor más la longitud de cada clave. Las actualizaciones que podrían provocar que se supere este límite fallan inmediatamente y establecen
runtime.lastError
cuando se usa una devolución de llamada o cuando se rechaza una promesa. -
QUOTA_BYTES_PER_ITEM
8,192
El tamaño máximo (en bytes) de cada elemento individual en el almacenamiento sincronizado, medido por la stringificación JSON de su valor más su longitud de clave. Las actualizaciones que contengan elementos que superen este límite fallarán inmediatamente y se configurarán
runtime.lastError
cuando se use una devolución de llamada o cuando se rechace una promesa.
Eventos
onChanged
chrome.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
-