javascript एचटीएमएल 5 स्थानीय स्टोरेज में ऑब्जेक्ट्स संग्रहीत करना




html5 local-storage (18)

मैं एचटीएमएल 5 localStorage में एक जावास्क्रिप्ट ऑब्जेक्ट स्टोर करना चाहता हूं, लेकिन मेरी ऑब्जेक्ट को स्पष्ट रूप से स्ट्रिंग में परिवर्तित किया जा रहा है।

मैं स्थानीय localStorage का उपयोग कर आदिम जावास्क्रिप्ट प्रकार और सरणी को स्टोर और पुनर्प्राप्त कर सकता हूं, लेकिन ऑब्जेक्ट्स काम नहीं कर रहे हैं। क्या उन्हें चाहिए?

मेरा कोड यहाँ है:

var testObject = { 'one': 1, 'two': 2, 'three': 3 };
console.log('typeof testObject: ' + typeof testObject);
console.log('testObject properties:');
for (var prop in testObject) {
    console.log('  ' + prop + ': ' + testObject[prop]);
}

// Put the object into storage
localStorage.setItem('testObject', testObject);

// Retrieve the object from storage
var retrievedObject = localStorage.getItem('testObject');

console.log('typeof retrievedObject: ' + typeof retrievedObject);
console.log('Value of retrievedObject: ' + retrievedObject);

कंसोल आउटपुट है

typeof testObject: object
testObject properties:
  one: 1
  two: 2
  three: 3
typeof retrievedObject: string
Value of retrievedObject: [object Object]

ऐसा लगता है कि setItem विधि इसे संग्रहीत करने से पहले एक स्ट्रिंग में इनपुट को परिवर्तित कर रहा है।

मैं सफारी, क्रोम और फ़ायरफ़ॉक्स में यह व्यवहार देखता हूं, इसलिए मुझे लगता है कि यह एचटीएमएल 5 वेब स्टोरेज स्पेक की मेरी गलतफहमी है, ब्राउज़र-विशिष्ट बग या सीमा नहीं।

मैंने http://www.w3.org/TR/html5/infrastructure.html में वर्णित संरचित क्लोन एल्गोरिदम का अर्थ बनाने की कोशिश की है। मैं पूरी तरह से समझ नहीं पा रहा हूं कि यह क्या कह रहा है, लेकिन हो सकता है कि मेरी समस्या को मेरे ऑब्जेक्ट के गुणों के साथ करना पड़ेगा (???)

क्या कोई आसान कामकाज है?

अद्यतन: W3C ने अंततः संरचित-क्लोन विनिर्देश के बारे में अपने दिमाग को बदल दिया, और कार्यान्वयन से मेल खाने के लिए spec को बदलने का फैसला किया। https://www.w3.org/Bugs/Public/show_bug.cgi?id=12111 देखें। तो यह सवाल अब 100% मान्य नहीं है, लेकिन उत्तर अभी भी ब्याज का हो सकता है।

https://code.i-harness.com


Stringify सभी समस्याओं को हल नहीं करता है

ऐसा लगता है कि यहां दिए गए उत्तरों में जावास्क्रिप्ट में संभव सभी प्रकार शामिल नहीं हैं, इसलिए यहां कुछ संक्षिप्त उदाहरण दिए गए हैं कि उनके साथ सही तरीके से कैसे निपटें:

//Objects and Arrays:
    var obj = {key: "value"};
    localStorage.object = JSON.stringify(obj);  //Will ignore private members
    obj = JSON.parse(localStorage.object);
//Boolean:
    var bool = false;
    localStorage.bool = bool;
    bool = (localStorage.bool === "true");
//Numbers:
    var num = 42;
    localStorage.num = num;
    num = +localStorage.num;    //short for "num = parseFloat(localStorage.num);"
//Dates:
    var date = Date.now();
    localStorage.date = date;
    date = new Date(parseInt(localStorage.date));
//Regular expressions:
    var regex = /^No\.[\d]*$/i;     //usage example: "No.42".match(regex);
    localStorage.regex = regex;
    var components = localStorage.regex.match("^/(.*)/([a-z]*)$");
    regex = new RegExp(components[1], components[2]);
//Functions (not recommended):
    function func(){}
    localStorage.func = func;
    eval( localStorage.func );      //recreates the function with the name "func"

मैं कार्यों को स्टोर करने की अनुशंसा नहीं करता क्योंकि eval() बुराई सुरक्षा, अनुकूलन और डिबगिंग के संबंध में मुद्दों का कारण बन सकती है। सामान्य रूप से, जावास्क्रिप्ट कोड में eval() का कभी भी उपयोग नहीं किया जाना चाहिए।

निजी सदस्य

वस्तुओं को संग्रहीत करने के लिए JSON.stringify() का उपयोग करने में समस्या यह है कि यह फ़ंक्शन निजी सदस्यों को क्रमबद्ध नहीं कर सकता है। इस समस्या को .toString() विधि को ओवरराइट करके हल किया जा सकता है (जिसे वेब स्टोरेज में डेटा संग्रहीत करते समय स्पष्ट रूप से कहा जाता है):

//Object with private and public members:
    function MyClass(privateContent, publicContent){
        var privateMember = privateContent || "defaultPrivateValue";
        this.publicMember = publicContent  || "defaultPublicValue";

        this.toString = function(){
            return '{"private": "' + privateMember + '", "public": "' + this.publicMember + '"}';
        };
    }
    MyClass.fromString = function(serialisedString){
        var properties = JSON.parse(serialisedString || "{}");
        return new MyClass( properties.private, properties.public );
    };
//Storing:
    var obj = new MyClass("invisible", "visible");
    localStorage.object = obj;
//Loading:
    obj = MyClass.fromString(localStorage.object);

परिपत्र संदर्भ

stringify एक और समस्या परिपत्र संदर्भों से निपट नहीं सकता है:

var obj = {};
obj["circular"] = obj;
localStorage.object = JSON.stringify(obj);  //Fails

इस उदाहरण में, JSON.stringify() एक JSON.stringify() " JSON.stringify() सर्कुलर स्ट्रक्चर जेएसओएन" फेंक देगा। यदि परिपत्र संदर्भों को संग्रहीत किया जाना चाहिए, तो JSON.stringify() का दूसरा पैरामीटर उपयोग किया जा सकता है:

var obj = {id: 1, sub: {}};
obj.sub["circular"] = obj;
localStorage.object = JSON.stringify( obj, function( key, value) {
    if( key == 'circular') {
        return "$ref"+value.id+"$";
    } else {
        return value;
    }
});

हालांकि, परिपत्र संदर्भों को संग्रहीत करने के लिए एक कुशल समाधान ढूंढना अत्यधिक उन कार्यों पर निर्भर करता है जिन्हें हल करने की आवश्यकता है, और ऐसे डेटा को बहाल करना भी छोटा नहीं है।

इस समस्या से निपटने के लिए एसओ पर पहले से ही कुछ सवाल हैं: सर्कुलर संदर्भ के साथ एक जावास्क्रिप्ट ऑब्जेक्ट स्ट्रिंगिफ़ (जेएसओएन में कनवर्ट करें)


@ गुरिया के उत्तर पर सुधार:

Storage.prototype.setObject = function (key, value) {
    this.setItem(key, JSON.stringify(value));
};


Storage.prototype.getObject = function (key) {
    var value = this.getItem(key);
    try {
        return JSON.parse(value);
    }
    catch(err) {
        console.log("JSON parse failed for lookup of ", key, "\n error was: ", err);
        return null;
    }
};

आप जावास्क्रिप्ट डेटा प्रकारों (ऐरे, बूलियन, दिनांक, फ्लोट, इंटीजर, स्ट्रिंग और ऑब्जेक्ट) को पारदर्शी रूप से स्टोर करने के लिए localDataStorage का उपयोग कर सकते हैं। यह लाइटवेट डेटा obfuscation भी प्रदान करता है, स्वचालित रूप से स्ट्रिंग को संपीड़ित करता है, कुंजी (नाम) के साथ-साथ क्वेरी (कुंजी) मान द्वारा क्वेरी की सुविधा देता है, और उपसर्ग कुंजी द्वारा एक ही डोमेन के भीतर विभाजित साझा भंडारण को लागू करने में मदद करता है।

[अस्वीकरण] मैं उपयोगिता का लेखक हूं [/ अस्वीकरण]

उदाहरण:

localDataStorage.set( 'key1', 'Belgian' )
localDataStorage.set( 'key2', 1200.0047 )
localDataStorage.set( 'key3', true )
localDataStorage.set( 'key4', { 'RSK' : [1,'3',5,'7',9] } )
localDataStorage.set( 'key5', null )

localDataStorage.get( 'key1' )   -->   'Belgian'
localDataStorage.get( 'key2' )   -->   1200.0047
localDataStorage.get( 'key3' )   -->   true
localDataStorage.get( 'key4' )   -->   Object {RSK: Array(5)}
localDataStorage.get( 'key5' )   -->   null

जैसा कि आप देख सकते हैं, आदिम मूल्यों का सम्मान किया जाता है।


आप डिफॉल्ट स्टोरेज setItem(key,value) ओवरराइड भी कर सकते हैं और किसी अन्य डेटा प्रकार की तरह ऑब्जेक्ट्स / एरे को संभालने के लिए getItem(key) विधियां प्राप्त कर सकते हैं। इस तरह, आप बस स्थानीय localStorage.setItem(key,value) और localStorage.getItem(key) को सामान्य रूप से कॉल कर सकते हैं।

मैंने इस बड़े पैमाने पर परीक्षण नहीं किया है, लेकिन यह एक छोटी परियोजना के लिए बिना किसी समस्या के काम करने के लिए काम कर रहा है जिसके साथ मैं झुका रहा हूं।

Storage.prototype._setItem = Storage.prototype.setItem;
Storage.prototype.setItem = function(key, value)
{
  this._setItem(key, JSON.stringify(value));
}

Storage.prototype._getItem = Storage.prototype.getItem;
Storage.prototype.getItem = function(key)
{  
  try
  {
    return JSON.parse(this._getItem(key));
  }
  catch(e)
  {
    return this._getItem(key);
  }
}

आपको इन आसान विधियों के साथ संग्रहण ऑब्जेक्ट को विस्तारित करना उपयोगी हो सकता है:

Storage.prototype.setObject = function(key, value) {
    this.setItem(key, JSON.stringify(value));
}

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

इस तरह आप उस कार्यक्षमता को प्राप्त करते हैं जिसे आप वास्तव में चाहते थे भले ही एपीआई के नीचे स्ट्रिंग का समर्थन करता हो।


एक variant पर मामूली सुधार:

Storage.prototype.setObject = function(key, value) {
    this.setItem(key, JSON.stringify(value));
}

Storage.prototype.getObject = function(key) {
    var value = this.getItem(key);
    return value && JSON.parse(value);
}

शॉर्ट-सर्किट मूल्यांकन के कारण , getObject() स्टोरेज में नहीं है तो getObject() तुरंत null हो जाएगा। यदि value "" (खाली स्ट्रिंग; JSON.parse() इसे संभाल नहीं सकता है तो यह JSON.parse() अपवाद भी नहीं फेंक देगा)।


एक महान पुस्तकालय है जो कई समाधानों को लपेटता है, इसलिए यह jStorage नामक पुराने ब्राउज़र का भी समर्थन करता है

आप एक वस्तु सेट कर सकते हैं

$.jStorage.set(key, value)

और इसे आसानी से पुनर्प्राप्त करें

value = $.jStorage.get(key)
value = $.jStorage.get(key, "default value")

टाइपस्क्रिप्ट उपयोगकर्ताओं को सेट करने और टाइप किए गए गुण प्राप्त करने के इच्छुक हैं:

/**
 * Silly wrapper to be able to type the storage keys
 */
export class TypedStorage<T> {

    public removeItem(key: keyof T): void {
        localStorage.removeItem(key);
    }

    public getItem<K extends keyof T>(key: K): T[K] | null {
        const data: string | null =  localStorage.getItem(key);
        return JSON.parse(data);
    }

    public setItem<K extends keyof T>(key: K, value: T[K]): void {
        const data: string = JSON.stringify(value);
        localStorage.setItem(key, data);
    }
}

उदाहरण का उपयोग :

// write an interface for the storage
interface MyStore {
   age: number,
   name: string,
   address: {city:string}
}

const storage: TypedStorage<MyStore> = new TypedStorage<MyStore>();

storage.setItem("wrong key", ""); // error unknown key
storage.setItem("age", "hello"); // error, age should be number
storage.setItem("address", {city:"Here"}); // ok

const address: {city:string} = storage.getItem("address");

मैं इस पोस्ट पर एक और पोस्ट पर मारने के बाद पहुंचा जो इसे डुप्लिकेट के रूप में बंद कर दिया गया है - शीर्षक 'स्थानीय स्टोरेज में एक सरणी कैसे स्टोर करें?'। जो ठीक है, न तो थ्रेड वास्तव में एक पूर्ण उत्तर प्रदान करता है कि आप स्थानीय स्टोरेज में एक सरणी कैसे बनाए रख सकते हैं - हालांकि मैंने दोनों धागे में मौजूद जानकारी के आधार पर समाधान तैयार करने में कामयाब रहा है।

तो यदि कोई और किसी सरणी के भीतर वस्तुओं को धक्का / पॉप / स्थानांतरित करने में सक्षम होना चाहता है, और वे चाहते हैं कि उस सरणी को स्थानीय स्टोरेज में संग्रहीत किया जाए या वास्तव में सत्रस्टॉरेज, आप यहां जाएं:

Storage.prototype.getArray = function(arrayName) {
  var thisArray = [];
  var fetchArrayObject = this.getItem(arrayName);
  if (typeof fetchArrayObject !== 'undefined') {
    if (fetchArrayObject !== null) { thisArray = JSON.parse(fetchArrayObject); }
  }
  return thisArray;
}

Storage.prototype.pushArrayItem = function(arrayName,arrayItem) {
  var existingArray = this.getArray(arrayName);
  existingArray.push(arrayItem);
  this.setItem(arrayName,JSON.stringify(existingArray));
}

Storage.prototype.popArrayItem = function(arrayName) {
  var arrayItem = {};
  var existingArray = this.getArray(arrayName);
  if (existingArray.length > 0) {
    arrayItem = existingArray.pop();
    this.setItem(arrayName,JSON.stringify(existingArray));
  }
  return arrayItem;
}

Storage.prototype.shiftArrayItem = function(arrayName) {
  var arrayItem = {};
  var existingArray = this.getArray(arrayName);
  if (existingArray.length > 0) {
    arrayItem = existingArray.shift();
    this.setItem(arrayName,JSON.stringify(existingArray));
  }
  return arrayItem;
}

Storage.prototype.unshiftArrayItem = function(arrayName,arrayItem) {
  var existingArray = this.getArray(arrayName);
  existingArray.unshift(arrayItem);
  this.setItem(arrayName,JSON.stringify(existingArray));
}

Storage.prototype.deleteArray = function(arrayName) {
  this.removeItem(arrayName);
}

उदाहरण उपयोग - स्थानीय स्टोरेज सरणी में सरल तारों को संग्रहीत करना:

localStorage.pushArrayItem('myArray','item one');
localStorage.pushArrayItem('myArray','item two');

उदाहरण उपयोग - सत्र में ऑब्जेक्ट संग्रह करना स्टोरेज सरणी:

var item1 = {}; item1.name = 'fred'; item1.age = 48;
sessionStorage.pushArrayItem('myArray',item1);

var item2 = {}; item2.name = 'dave'; item2.age = 22;
sessionStorage.pushArrayItem('myArray',item2);

सरणी में हेरफेर करने के लिए सामान्य तरीके:

.pushArrayItem(arrayName,arrayItem); -> adds an element onto end of named array
.unshiftArrayItem(arrayName,arrayItem); -> adds an element onto front of named array
.popArrayItem(arrayName); -> removes & returns last array element
.shiftArrayItem(arrayName); -> removes & returns first array element
.getArray(arrayName); -> returns entire array
.deleteArray(arrayName); -> removes entire array from storage

मैंने एक शीर्ष वोट वाले उत्तर में से एक को संशोधित किया है। यदि आवश्यक नहीं है तो मैं 2 की बजाय एकल फ़ंक्शन रखने का प्रशंसक हूं।

Storage.prototype.object = function(key, val) {
    if ( typeof val === "undefined" ) {
        var value = this.getItem(key);
        return value ? JSON.parse(value) : null;
    } else {
        this.setItem(key, JSON.stringify(val));
    }
}

localStorage.object("test", {a : 1}); //set value
localStorage.object("test"); //get value

इसके अलावा, यदि कोई मान सेट नहीं किया गया है, तो यह false जगह के बदले null रहा है। false कुछ अर्थ है, null नहीं है।


मैंने कोड का केवल 20 लाइनों के साथ एक और सरल रैपर बनाया है ताकि इसे इस्तेमाल करने की अनुमति दी जा सके:

localStorage.set('myKey',{a:[1,2,5], b: 'ok'});
localStorage.has('myKey');   // --> true
localStorage.get('myKey');   // --> {a:[1,2,5], b: 'ok'}
localStorage.keys();         // --> ['myKey']
localStorage.remove('myKey');

https://github.com/zevero/simpleWebstorage


यहां चर्चा की गई कई विशेषताओं के साथ-साथ बेहतर संगतता के लिए एक अमूर्त पुस्तकालय का उपयोग करने की सिफारिश करें। बहुत सारे विकल्प:


स्टोरेज ऑब्जेक्ट को विस्तार करना एक शानदार समाधान है। मेरे एपीआई के लिए, मैंने स्थानीय स्टोरेज के लिए एक मुखौटा बनाया है और फिर जांच करें कि यह एक ऑब्जेक्ट है या नहीं, जबकि सेटिंग और हो रही है।

var data = {
  set: function(key, value) {
    if (!key || !value) {return;}

    if (typeof value === "object") {
      value = JSON.stringify(value);
    }
    localStorage.setItem(key, value);
  },
  get: function(key) {
    var value = localStorage.getItem(key);

    if (!value) {return;}

    // assume it is an object that has been stringified
    if (value[0] === "{") {
      value = JSON.parse(value);
    }

    return value;
  }
}

स्थानीय भंडारण के लिए JSON ऑब्जेक्ट्स का उपयोग करना:

//सेट

var m={name:'Hero',Title:'developer'};
localStorage.setItem('us', JSON.stringify(m));

//प्राप्त

var gm =JSON.parse(localStorage.getItem('us'));
console.log(gm.name);

// सभी स्थानीय भंडारण कुंजी और मूल्यों का Iteration

for (var i = 0, len = localStorage.length; i < len; ++i) {
  console.log(localStorage.getItem(localStorage.key(i)));
}

// हटाएं

localStorage.removeItem('us');
delete window.localStorage["us"];

http://rhaboo.org एक स्थानीय स्टोरेज चीनी परत है जो आपको इस तरह की चीजें लिखने देती है:

var store = Rhaboo.persistent('Some name');
store.write('count', store.count ? store.count+1 : 1);
store.write('somethingfancy', {
  one: ['man', 'went'],
  2: 'mow',
  went: [  2, { mow: ['a', 'meadow' ] }, {}  ]
});
store.somethingfancy.went[1].mow.write(1, 'lawn');

यह JSON.stringify / parse का उपयोग नहीं करता है क्योंकि यह बड़ी वस्तुओं पर गलत और धीमा होगा। इसके बजाय, प्रत्येक टर्मिनल मान की अपनी स्थानीय स्टोरेज प्रविष्टि होती है।

आप शायद अनुमान लगा सकते हैं कि मुझे राभू के साथ कुछ करना पड़ सकता है ;-)

एड्रियन।


इस देखो

मान लीजिए कि आपके पास मूवी नामक निम्न सरणी है:

var movies = ["Reservoir Dogs", "Pulp Fiction", "Jackie Brown", 
              "Kill Bill", "Death Proof", "Inglourious Basterds"];

स्ट्रिंगफाई फ़ंक्शन का उपयोग करके, आपकी फिल्म सरणी को निम्न वाक्यविन्यास का उपयोग कर स्ट्रिंग में बदल दिया जा सकता है:

localStorage.setItem("quentinTarantino", JSON.stringify(movies));

ध्यान दें कि मेरा डेटा quentinTarantino नामक कुंजी के तहत संग्रहीत किया जा रहा है।

अपना डेटा पुनर्प्राप्त करना

var retrievedData = localStorage.getItem("quentinTarantino");

एक स्ट्रिंग से किसी ऑब्जेक्ट में कनवर्ट करने के लिए, JSON पार्स फ़ंक्शन का उपयोग करें:

var movies2 = JSON.parse(retrievedData);

आप अपनी फिल्म 2 पर सभी सरणी विधियों को कॉल कर सकते हैं


मुझे स्थानीय, सत्र, कुकीज़ पर उन तरह की समस्या से बचने के लिए लगता है आप opendb लाइब्रेरी का उपयोग कर सकते हैं ..

पूर्व- जिसमें आप इस स्निपेट का उपयोग करके इसे हल कर सकते हैं

// for set object in db
db.local.setJSON("key", {name: "xyz"});  

// for get object form db
db.local.getJSON("key");

https://github.com/pankajbisht/openDB

वेब स्टोरेज के बारे में अधिक जानकारी के लिए आप वेब स्टोरेज आलेख पढ़ सकते हैं ।


संपर्कों से प्राप्त संदेशों का ट्रैक रखने के लिए स्थानीय स्टोरेज का उपयोग करने वाली लाइब्रेरी का एक छोटा सा उदाहरण:

// This class is supposed to be used to keep a track of received message per contacts.
// You have only four methods:

// 1 - Tells you if you can use this library or not...
function isLocalStorageSupported(){
    if(typeof(Storage) !== "undefined" && window['localStorage'] != null ) {
         return true;
     } else {
         return false;
     }
 }

// 2 - Give the list of contacts, a contact is created when you store the first message
 function getContacts(){
    var result = new Array();
    for ( var i = 0, len = localStorage.length; i < len; ++i ) {
        result.push(localStorage.key(i));
    }
    return result;
 }

 // 3 - store a message for a contact
 function storeMessage(contact, message){
    var allMessages;
    var currentMessages = localStorage.getItem(contact);
    if(currentMessages == null){
        var newList = new Array();
        newList.push(message);
        currentMessages = JSON.stringify(newList);
    }
    else
    {
        var currentList =JSON.parse(currentMessages);
        currentList.push(message);
        currentMessages = JSON.stringify(currentList);
    }
    localStorage.setItem(contact, currentMessages);
 }

 // 4 - read the messages of a contact
 function readMessages(contact){

    var result = new Array();
    var currentMessages = localStorage.getItem(contact);

    if(currentMessages != null){
        result =JSON.parse(currentMessages);
    }
    return result;
 }




local-storage