Enregistrer les objets Javascript dans sessionStorage

152

SessionStorage et LocalStorage permettent d'enregistrer des paires clé / valeur dans un navigateur Web. La valeur doit être une chaîne et enregistrer les objets js n'est pas trivial.

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

De nos jours, vous pouvez éviter cette limitation en sérialisant les objets en JSON, puis en les désérialisant pour récupérer les objets. Mais l'API de stockage passe toujours par les méthodes setItemet getItem.

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

Puis-je éviter cette limitation?

Je veux juste exécuter quelque chose comme ceci:

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

J'ai essayé les méthodes defineGetteret defineSetterpour intercepter les appels, mais c'est un travail fastidieux, car je dois définir toutes les propriétés et ma cible n'est pas de connaître les propriétés futures.

Ferran Basora
la source
1
J'y ai pensé moi-même. Je suppose que beaucoup de gens l'ont fait. Mais je ne pense pas que les méthodes getter et setter soient trop lourdes. BTW; vous pouvez sérialiser et analyser avec JavaScript et MS prend enfin en charge les mêmes objets standard que tout le monde. L'époque du besoin de packages tels que JSON et jQuery touche à sa fin.
Roger F. Gay
1
Je suppose que je ne vois pas la limitation. Il peut sembler excessif d'utiliser JSON.stringify et JSON.parse si vous n'avez que des objets triviaux, mais si vous avez même des objets de données de bonne taille, ces deux méthodes font beaucoup de travail pour vous.
Robusto
5
"Puis-je éviter cette limitation?" semble être une question
sonicblis
1
Eh bien limitation ou pas, cette question m'a aidé à résoudre un problème, alors merci.
Matt West

Réponses:

19

Soit vous pouvez utiliser les accesseurs fournis par l'API de stockage Web, soit vous pouvez écrire un wrapper / adaptateur. D'après votre problème déclaré avec defineGetter / defineSetter, il semble que l'écriture d'un wrapper / adaptateur est trop de travail pour vous.

Honnêtement, je ne sais pas quoi te dire. Peut-être pourriez-vous réévaluer votre opinion sur ce qu'est une «limitation ridicule». L'API de stockage Web est exactement ce qu'elle est censée être, un magasin de clés / valeurs.

Ryan Olds
la source
8
Désolé si j'ai utilisé un mot inapproprié avec «ridicule». Remplacez-le par «pourrait être si intéressant». Je pense que le webStorage est l'une des améliorations les plus intéressantes du nouveau web. Mais ne sauvegardez que les chaînes dans le key-map de valeur, je pense que c'est une limitation. Cela ressemble à une suite de cookies. Je sais que le stockage est une spécification non seulement pour le langage Javascript, mais la sérialisation des objets pourrait être une amélioration intéressante. Qu'est-ce que tu penses?
Ferran Basora
2
Si JSON ne suffit pas, vous pouvez toujours écrire vos propres méthodes de sérialisation d'objets.
Ryan Olds
110

Ne pourriez-vous pas «stringifier» votre objet ... puis l'utiliser sessionStorage.setItem()pour stocker cette représentation sous forme de chaîne de votre objet ... puis quand vous en avez besoin sessionStorage.getItem()et ensuite l'utiliser $.parseJSON()pour le récupérer?

Exemple de travail http://jsfiddle.net/pKXMa/

afreeland
la source
Cela fonctionne pour moi. J'obtiens un objet Json fonctionnel après avoir appelé $ .parseJSON ()
Olafur Tryggvason
Certains systèmes comme l'authentification Web Api renvoient des objets sous la forme Object {propertyOneWithoutQuotes: "<value1>", ... propertyNWithoutQuotes: "<valueN>"} qui doivent passer par "stringify". S'il existe plusieurs sources, il peut être préférable d'utiliser stringify pour standardiser les données.
Jelgab
C'est une très bonne réponse. Il est bon d'utiliser JSON.stringify () pour sérialiser l'objet et le stocker dans sessionStorage. Ensuite, il utilise $ .parseJSON () pour désérialiser la chaîne afin d'obtenir l'objet.
Thomas.Benz
102

La solution consiste à stringifier l'objet avant d'appeler setItem sur sessionStorage.

var user = {'name':'John'};
sessionStorage.setItem('user', JSON.stringify(user));
var obj = JSON.parse(sessionStorage.user);
Ron
la source
Merci de ne pas lier la solution
Luc-Olsthoorn
12

Il s'agit d'une solution dynamique qui fonctionne avec tous les types de valeur, y compris les objets:

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

Ensuite :

const session = new Session();

session.set('name', {first: 'Ahmed', last : 'Toumi'});
session.get('name');
Abdennour TOUMI
la source
5

Cas d'utilisation:

 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))
    };
Abdennour TOUMI
la source
4
Je pensais que l'une des meilleures pratiques en javascript était de ne pas prototyper des objets que vous ne possédez pas. Utiliser Storage.prototype.setObj semble être une mauvaise idée.
britztopher
3
il suffit d'ajouter l'obligatoire .. assurez-vous de ne pas ajouter ce code prototype - et de vous y fier exclusivement - sans d'abord vérifier si le navigateur le prend en charge Stockage:if (typeof (Storage) !== "undefined"){ /* browser supports it */ }
JoeBrockhaus
4

Le stockage de session ne peut pas prendre en charge un objet arbitraire car il peut contenir des littéraux de fonction (fermetures de lecture) qui ne peuvent pas être reconstruits après un rechargement de page.

Igor Urisman
la source
3
    var user = {'name':'John'};
    sessionStorage['user'] = JSON.stringify(user);
    console.log(sessionStorage['user']);
Jijo Paulose
la source
2

Vous pouvez également utiliser la bibliothèque de magasin qui l'exécute pour vous avec la capacité de crossbrowser.

exemple :

// 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)
})
3Dos
la source
0

Vous pouvez créer 2 méthodes de wrapper pour enregistrer et récupérer des objets à partir du stockage de session.

function saveSession(obj) {
  sessionStorage.setItem("myObj", JSON.stringify(obj));
  return true;
}

function getSession() {
  var obj = {};
  if (typeof sessionStorage.myObj !== "undefined") {
    obj = JSON.parse(sessionStorage.myObj);
  }
  return obj;
}

Utilisez-le comme ceci: - Obtenez un objet, modifiez certaines données et enregistrez-le.

var obj = getSession();

obj.newProperty = "Prod"

saveSession(obj);
JerryGoyal
la source