2011-05-31 32 views
102

SessionStorage y LocalStorage permite guardar pares clave/valor en un navegador web. El valor debe ser una cadena y guardar objetos js no es trivial.Guardar objetos de Javascript en sessionStorage

var user = {'name':'John'}; 
sessionStorage.setItem('user', user); 
var obj = sessionStorage.user; // obj='[object Object]' Not an object 

Hoy en día, se puede evitar esta limitación seria objetos a JSON, y luego deserializar para recuperar los objetos. Pero la API de almacenamiento siempre pasa por los métodos setItem y getItem.

sessionStorage.setItem('user', JSON.stringify(user)); 
var obj = JSON.parse(sessionStorage.getItem('user')); // An object :D 

¿Puedo evitar esta limitación?

sólo quiero ejecutar algo como esto:

sessionStorage.user.name; // 'John' 
sessionStorage.user.name = 'Mary'; 
sessionStorage.user.name // 'Mary' 

He probado los defineGetter y defineSetter métodos para interceptar las llamadas, pero es un trabajo tedioso, porque tengo que definir todas las propiedades y mi objetivo no es para conocer las propiedades futuras.

+1

he pensado en eso mismo. Supongo que mucha gente tiene. Pero no creo que los métodos getter y setter sean una carga excesiva. Por cierto; puede serializar y analizar con JavaScript y MS finalmente admite los mismos objetos estándar que cualquier otra persona. Los días de necesidad de paquetes como JSON y jQuery están llegando rápidamente a su fin. –

+1

Supongo que no veo la limitación. Puede parecer exagerado utilizar JSON.stringify y JSON.parse si solo tiene objetos triviales, pero si tiene incluso objetos de datos de buen tamaño, esos dos métodos le están haciendo un gran esfuerzo. – Robusto

+5

"¿Puedo evitar esta limitación?" parece una pregunta – sonicblis

Respuesta

16

O puede usar los accesos proporcionados por la API de almacenamiento web o puede escribir un envoltorio/adaptador. Desde su problema establecido con defineGetter/defineSetter suena como escribir un wrapper/adaptador que es demasiado trabajo para usted.

Honestamente, no sé qué decirte. Tal vez podrías reevaluar tu opinión sobre lo que es una "limitación ridícula". La API de almacenamiento web es exactamente lo que se supone que es, un almacén de claves/valores.

+4

Lo siento si he usado una palabra inapropiada con 'ridículo'. Reemplácelo con 'podría ser tan interesante'. Creo que webStorage es una de las mejoras más interesantes de la nueva web. Pero guarde solo cadenas en el mapa-clave de valor, creo que es una limitación. Parece una secuela de cookies. Sé que el Almacenamiento es una especificación no solo para el lenguaje Javascript, pero serializar objetos podría ser una mejora interesante. ¿Qué piensas? –

+1

Si JSON no es suficiente, siempre puede escribir sus propios métodos de serialización de objetos. –

+1

La respuesta más estúpida que incluso va en contra de las reglas de SO. Downvoted. – sidney

86

¿No podría 'stringify' su objeto ... luego use sessionStorage.setItem() para almacenar esa representación de cadena de su objeto ... entonces cuando lo necesite sessionStorage.getItem() y luego use $.parseJSON() para volverlo a sacar?

Ejemplo de trabajo http://jsfiddle.net/pKXMa/

+0

Esto funciona para mí. Obtengo un objeto Json que funciona después de llamar $ .parseJSON() –

+0

Algunos sistemas como autenticación Web Api devuelven objetos en forma de Objeto {propertyOneWithoutQuotes: "", ... propiedadNWithoutQuotes: ""} que deben pasar por "stringify" ". Si hay varias fuentes, podría ser mejor usar stringify para estandarizar los datos. – Jelgab

+0

Esta es una muy buena respuesta. Es bueno usar JSON.stringify() para serializar el objeto y almacenarlo en sessionStorage. Luego, usa $ .parseJSON() para deserializar la cadena para obtener el objeto. –

5

Caso de uso:

sesssionStorage.setObj(1,{date:Date.now(),action:'save firstObject'}); 
sesssionStorage.setObj(2,{date:Date.now(),action:'save 2nd object'}); 
//Query first object 
    sesssionStorage.getObj(1) 
    //Retrieve date created of 2nd object 
    new Date(sesssionStorage.getObj(1).date) 

API

Storage.prototype.setObj = function(key, obj) { 

     return this.setItem(key, JSON.stringify(obj)) 
    }; 

    Storage.prototype.getObj = function(key) { 
     return JSON.parse(this.getItem(key)) 
    }; 
+2

Pensé que una de las mejores prácticas en JavaScript era no crear prototipos de objetos que no le pertenecían. Usar Storage.prototype.setObj parece una mala idea. – britztopher

+0

créanme. es una buena idea, excepto el objeto Object en sí mismo –

+3

simplemente agregando el obligatorio ... asegúrese de no agregar este código de prototipo, y confíe en él exclusivamente, sin verificar primero si el navegador lo admite Almacenamiento: 'if (typeof (Almacenamiento) ! == "undefined") {/ * el navegador lo admite * /} ' – JoeBrockhaus

49

La solución es stringify el objeto antes de llamar setItem en el sessionStorage.

var user = {'name':'John'}; 
sessionStorage.setItem('user', JSON.stringify(user)); 
var obj = JSON.parse(sessionStorage.user); 
1
var user = {'name':'John'}; 
    sessionStorage['user'] = JSON.stringify(user); 
    console.log(sessionStorage['user']); 
3

Ésta es una solución dinámica que funciona con todos los tipos de valores que incluyen objetos:

class Session extends Map { 
    set(id, value) { 
    if (typeof value === 'object') value = JSON.stringify(value); 
    sessionStorage.setItem(id, value); 
    } 

    get(id) { 
    const value = sessionStorage.getItem(id); 
    try { 
     return JSON.parse(value); 
    } catch (e) { 
     return value; 
    } 
    } 
} 

continuación:

const session = new Session(); 

session.set('name', {first: 'Ahmed', last : 'Toumi'}); 
session.get('name'); 
+0

Bueno, pero no funciona con funciones. – RSG

0

También es posible usar el store library que lleva a cabo para tú con la habilidad del navegador cruzado.

ejemplo:

// Store current user 
store.set('user', { name:'Marcus' }) 

// Get current user 
store.get('user') 

// Remove current user 
store.remove('user') 

// Clear all keys 
store.clearAll() 

// Loop over all stored values 
store.each(function(value, key) { 
    console.log(key, '==', value) 
})