IndexedDB es una de las capacidades de almacenamiento introducidas en los navegadores a lo largo de los años. Aquí hay una introducción a IndexedDB, la base de datos de la Web compatible con todos los navegadores modernos.
- Introducción a IndexedDB
- Crear una base de datos IndexedDB
- Agregar datos a una tienda
- Obtener datos de una tienda
- Eliminando datos de IndexedDB
- Migrar desde la versión anterior de una base de datos
- Llaves únicas
- Eliminando de IndexedDB
- ¡Hay más!
Introducción a IndexedDB
IndexedDB es una de las capacidades de almacenamiento introducidas en los navegadores a lo largo de los años. Es un almacén de clave / valor (una base de datos noSQL) que se considerala solución definitiva para almacenar datos en navegadores.
Es una API asincrónica, lo que significa que la realización de operaciones costosas no bloqueará el hilo de la interfaz de usuario, proporcionando una experiencia descuidada a los usuarios. Puede almacenar una cantidad indefinida de datos, aunque una vez que se sobrepasa un cierto umbral, se le pide al usuario que le dé al sitio límites más altos.
Escompatible con todos los navegadores modernos.
Admite transacciones, control de versiones y ofrece un buen rendimiento.
Dentro del navegador también podemos utilizar:
- Galletas: puede albergar una cantidad muy pequeña de cadenas
- Almacenamiento web(o almacenamiento DOM), un término que comúnmente identifica localStorage y sessionStorage, dos almacenes clave / valor. sessionStorage, no retiene datos, que se borran cuando finaliza la sesión, mientras que localStorage mantiene los datos entre sesiones
El almacenamiento local / de sesión tiene la desventaja de estar limitado a un tamaño pequeño (e inconsistente), con la implementación de los navegadores que ofrecen de 2 MB a 10 MB de espacio por sitio.
En el pasado también tuvimosWeb SQL, una envoltura alrededor de SQLite, pero ahora esto esobsoletoy no es compatible con algunos navegadores modernos, nunca ha sido un estándar reconocido y, por lo tanto, no debe usarse, aunque el 83% de los usuarios tienen esta tecnología en sus dispositivos.de acuerdo con puedo usar.
Aunque técnicamente puede crear varias bases de datos por sitio, generalmentecrear una sola base de datos, y dentro de esa base de datos puedes crearmúltiples almacenes de objetos.
Una base de datos esprivado a un dominio, por lo que cualquier otro sitio no puede acceder a otro sitio web de las tiendas IndexedDB.
Cada tienda suele contener un conjunto decosas, que puede ser
- instrumentos de cuerda
- números
- objetos
- matrices
- fechas
Por ejemplo, puede tener una tienda que contenga publicaciones, otra que contenga comentarios.
Una tienda contiene una serie de artículos que tienen una clave única, que representa la forma en que se puede identificar un objeto.
Puede modificar esas tiendas mediante transacciones, realizando operaciones de agregar, editar y eliminar, e iterar sobre los artículos que contienen.
Desde el advenimiento dePromesasen ES6, y el posterior movimiento de las API para usar promesas, la API IndexedDB parece un pocovieja escuela.
Si bien no hay nada de malo en ello, en todos los ejemplos que explicaré usaré elBiblioteca prometida de IndexedDBpor Jake Archibald, que es una pequeña capa encima de la API IndexedDB para que sea más fácil de usar.
Esta biblioteca también se utiliza en todos los ejemplos en el sitio web de Google Developers con respecto a IndexedDB
Crear una base de datos IndexedDB
La forma más sencilla es utilizarunpkg, agregando esto al encabezado de la página:
<script type="module">
import { openDB, deleteDB } from 'https://unpkg.com/idb?module'
</script>
Antes de usar la API IndexedDB, asegúrese siempre de verificar la compatibilidad en el navegador, aunque está ampliamente disponible, nunca se sabe qué navegador está usando el usuario:
(() => {
'use strict'
if (!(‘indexedDB’ in window)) {
console.warn(‘IndexedDB not supported’)
return
}
//…IndexedDB code
})()
Cómocrear una base de datos
UsandoopenDB()
:
(async () => {
//...
const dbName = 'mydbname'
const storeName = 'store1'
const version = 1 //versions start at 1
const db = await openDB(dbName, version, {
upgrade(db, oldVersion, newVersion, transaction) {
const store = db.createObjectStore(storeName)
}
})
})()
Los primeros 2 parámetros son el nombre de la base de datos y la versión. El tercer parámetro, que es opcional, es un objeto que contiene una funciónse llama solo si el número de versión es mayor que la versión actual de la base de datos instalada. En el cuerpo de la función puede actualizar la estructura (almacenes e índices) del archivo db.
Agregar datos a una tienda
Agregar datos cuando se crea la tienda, inicializarla
Usas elput
método del almacén de objetos, pero primero necesitamos una referencia a él, que podemos obtener dedb.createObjectStore()
cuando lo creamos.
Cuando usasput
, el valor es el primer argumento, la clave es el segundo. Esto se debe a que si especificakeyPath
al crear el almacén de objetos, no es necesario que ingrese el nombre de la clave en cada solicitud put (), solo puede escribir el valor.
Esto pueblastore0
tan pronto como lo creamos:
(async () => {
//...
const dbName = 'mydbname'
const storeName = 'store0'
const version = 1
const db = await openDB(dbName, version,{
upgrade(db, oldVersion, newVersion, transaction) {
const store = db.createObjectStore(storeName)
store.put(‘Hello world!’, ‘Hello’)
}
})
})()
Agregar datos cuando la tienda ya está creada, usando transacciones
Para agregar elementos más adelante en el futuro, debe crear una lectura / escrituratransacción, que asegura la integridad de la base de datos (si una operación falla, todas las operaciones de la transacción se revierten y el estado vuelve a un estado conocido).
Para eso, use una referencia aldbPromise
objeto que obtuvimos al llamaropenDB
, y correr:
(async () => {
//...
const dbName = 'mydbname'
const storeName = 'store0'
const version = 1
const db = await openDB(/* … */)
const tx = db.transaction(storeName, ‘readwrite’)
const store = await tx.objectStore(storeName)
const val = ‘hey!’
const key = ‘Hello again’
const value = await store.put(val, key)
await tx.done
})()
Obtener datos de una tienda
Obtener un artículo de una tienda:get()
const key = 'Hello again'
const item = await db.transaction(storeName).objectStore(storeName).get(key)
Obtener todos los artículos de una tienda:getAll()
Obtener todas las claves almacenadas
const items = await db.transaction(storeName).objectStore(storeName).getAllKeys()
Obtenga todos los valores almacenados
const items = await db.transaction(storeName).objectStore(storeName).getAll()
Eliminando datos de IndexedDB
Eliminar la base de datos, un almacén de objetos y datos
Eliminar una base de datos IndexedDB completa
const dbName = 'mydbname'
await deleteDB(dbName)
Para eliminar datos en un almacén de objetos
Usamos una transacción:
(async () => {
//...
const dbName = 'mydbname'
const storeName = 'store1'
const version = 1
const db = await openDB(dbName, version, {
upgrade(db, oldVersion, newVersion, transaction) {
const store = db.createObjectStore(storeName)
}
})
const tx = await db.transaction(storeName, ‘readwrite’)
const store = await tx.objectStore(storeName)
const key = ‘Hello again’
await store.delete(key)
await tx.done
})()
Migrar desde la versión anterior de una base de datos
El tercer parámetro (opcional) delopenDB()
La función es un objeto que puede contener unupgrade
funciónse llama solo si el número de versión es mayor que la versión actual de la base de datos instalada. En ese cuerpo de función puede actualizar la estructura (tiendas e índices) de la base de datos:
const name = 'mydbname'
const version = 1
openDB(name, version, {
upgrade(db, oldVersion, newVersion, transaction) {
console.log(oldVersion)
}
})
En esta devolución de llamada, puede verificar desde qué versión está actualizando el usuario y realizar algunas operaciones en consecuencia.
Puede realizar una migración desde una versión anterior de la base de datos utilizando esta sintaxis
(async () => {
//...
const dbName = 'mydbname'
const storeName = 'store0'
const version = 1
const db = await openDB(dbName, version, {
upgrade(db, oldVersion, newVersion, transaction) {
switch (oldVersion) {
case 0: // no db created before
// a store introduced in version 1
db.createObjectStore(‘store1’)
case 1:
// a new store in version 2
db.createObjectStore(‘store2’, { keyPath: ‘name’ })
}
db.createObjectStore(storeName)
}
})
})()
Llaves únicas
createObjectStore()
como puedes ver encase 1
acepta un segundo parámetro que indica la clave de índice de la base de datos. Esto es muy útil cuando almacena objetos:put()
las llamadas no necesitan un segundo parámetro, pero pueden simplemente tomar el valor (un objeto) y la clave se asignará a la propiedad del objeto que tiene ese nombre.
El índice le brinda una forma de recuperar un valor más tarde mediante esa clave específica, y debe ser único (cada elemento debe tener una clave diferente)
Se puede configurar una clave para que aumente automáticamente, por lo que no es necesario realizar un seguimiento de ella en el código del cliente:
db.createObjectStore('notes', { autoIncrement: true })
Utilice el incremento automático si sus valores aún no contienen una clave única (por ejemplo, si recopila direcciones de correo electrónico sin un nombre asociado).
Comprueba si existe una tienda
Puede comprobar si ya existe un almacén de objetos llamando alobjectStoreNames()
método:
const storeName = 'store1'
if (!db.objectStoreNames.contains(storeName)) {
db.createObjectStore(storeName)
}
Eliminando de IndexedDB
Eliminar la base de datos, un almacén de objetos y datos
Eliminar una base de datos
await deleteDB('mydb')
Eliminar un almacén de objetos
Un almacén de objetos solo se puede eliminar en la devolución de llamada al abrir una base de datos, y esa devolución de llamada solo se llama si especifica una versión superior a la que está instalada actualmente:
const db = await openDB('dogsdb', 2, {
upgrade(db, oldVersion, newVersion, transaction) {
switch (oldVersion) {
case 0: // no db created before
// a store introduced in version 1
db.createObjectStore('store1')
case 1:
// delete the old store in version 2, create a new one
db.deleteObjectStore('store1')
db.createObjectStore('store2')
}
}
})
Para eliminar datos en una tienda de objetos, use una transacción
const key = 232 //a random key
const db = await openDB(/*...*/)
const tx = await db.transaction('store', 'readwrite')
const store = await tx.objectStore('store')
await store.delete(key)
await tx.complete
¡Hay más!
Estos son solo los conceptos básicos. No hablé de cursores y cosas más avanzadas. Hay más en IndexedDB, pero espero que esto le dé una ventaja.
Descarga mi gratisManual para principiantes de JavaScript
Más tutoriales de navegador:
- Algunos trucos útiles disponibles en HTML5
- Cómo hice que un sitio web basado en CMS funcionara sin conexión
- La guía completa de aplicaciones web progresivas
- La API de Fetch
- La guía Push API
- La API de mensajería de canal
- Tutorial para trabajadores de servicios
- La guía de la API de caché
- La guía de la API de notificaciones
- Sumérjase en IndexedDB
- La API de selectores: querySelector y querySelectorAll
- Cargue JavaScript de forma eficiente con diferir y asincrónico
- El modelo de objetos de documento (DOM)
- La API de almacenamiento web: almacenamiento local y almacenamiento de sesiones
- Descubra cómo funcionan las cookies HTTP
- La API de historia
- El formato de imagen WebP
- XMLHttpRequest (XHR)
- Un tutorial detallado de SVG
- ¿Qué son las URL de datos?
- Hoja de ruta para aprender la plataforma web
- CORS, intercambio de recursos de origen cruzado
- Trabajadores web
- La guía requestAnimationFrame ()
- Que es el Doctype
- Trabajar con la consola de DevTools y la API de la consola
- La API de síntesis de voz
- Cómo esperar el evento DOM Ready en JavaScript simple
- Cómo agregar una clase a un elemento DOM
- Cómo recorrer los elementos DOM de querySelectorAll
- Cómo eliminar una clase de un elemento DOM
- Cómo comprobar si un elemento DOM tiene una clase
- Cómo cambiar un valor de nodo DOM
- Cómo agregar un evento de clic a una lista de elementos DOM devueltos por querySelectorAll
- WebRTC, la API web en tiempo real
- Cómo obtener la posición de desplazamiento de un elemento en JavaScript
- Cómo reemplazar un elemento DOM
- Cómo aceptar solo imágenes en un campo de archivo de entrada
- ¿Por qué utilizar una versión de vista previa de un navegador?
- El objeto Blob
- El objeto de archivo
- El objeto FileReader
- El objeto FileList
- ArrayBuffer
- ArrayBufferView
- El objeto URL
- Matrices escritas
- El objeto DataView
- La API BroadcastChannel
- La API de Streams
- El objeto FormData
- El objeto del navegador
- Cómo utilizar la API de geolocalización
- Cómo utilizar getUserMedia ()
- Cómo utilizar la API de arrastrar y soltar
- Cómo trabajar con el desplazamiento en páginas web
- Manejo de formularios en JavaScript
- Eventos de teclado
- Eventos del mouse
- Toque eventos
- Cómo eliminar a todos los hijos de un elemento DOM
- Cómo crear un atributo HTML usando Vanilla Javascript
- ¿Cómo verificar si una casilla de verificación está marcada usando JavaScript?
- Cómo copiar al portapapeles usando JavaScript
- Cómo deshabilitar un botón usando JavaScript
- Cómo hacer que una página sea editable en el navegador
- Cómo obtener valores de cadena de consulta en JavaScript con URLSearchParams
- Cómo eliminar todo el CSS de una página a la vez
- Cómo utilizar insertAdjectedHTML
- Safari, avisa antes de salir
- Cómo agregar una imagen al DOM usando JavaScript
- Cómo restablecer un formulario
- Cómo utilizar las fuentes de Google