HTML5 लोकलस्टोरेज में ऑब्जेक्ट्स को स्टोर करना


2510

मैं HTML5 में जावास्क्रिप्ट ऑब्जेक्ट को स्टोर करना चाहता हूं 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 में वर्णित संरचित क्लोन एल्गोरिथ्म की समझ बनाने की कोशिश की है । मुझे पूरी तरह से समझ में नहीं आ रहा है कि यह क्या कह रहा है, लेकिन शायद मेरी समस्या का मेरे ऑब्जेक्ट के गुणों के साथ enumerable (???) नहीं है

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


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


17
BTW, "संरचित क्लोन एल्गोरिथ्म" का आपका पढ़ना सही है, यह सिर्फ यह है कि कार्यान्वयन से बाहर होने के बाद स्ट्रिंग को केवल मूल्यों से बदल दिया गया था। मैंने इस मुद्दे को ट्रैक करने के लिए mozilla के साथ बग Bugzilla.mozilla.org/show_bug.cgi?id=538142 दर्ज किया ।
निकोले

2
यह IndexedDB के लिए एक नौकरी की तरह लगता है ...
markasoftware

1
कैसे स्थानीयस्टोरेज में ऑब्जेक्ट्स की एक सरणी को स्टोर करने के बारे में? मैं एक ही समस्या का सामना कर रहा हूं कि यह स्ट्रिंग में परिवर्तित हो रहा है।
जयंत पारीक

1
आप इसके बजाय सिर्फ सरणी क्रमबद्ध कर सकते हैं? JSON के साथ स्टोर की तरह फिर लोडिंग पर फिर से पार्स करें?
ब्रैंडिटो

1
आप पारदर्शी डेटा प्रकारों (एरे, बूलियन, दिनांक, फ्लोट, इंटेगर, स्ट्रिंग और ऑब्जेक्ट) को स्टोर करने के लिए लोकलडॉटस्टोरेज का उपयोग कर सकते हैं
मैक

जवाबों:


3169

को देखते हुए एप्पल , मोज़िला और मोज़िला फिर प्रलेखन, कार्यक्षमता केवल स्ट्रिंग कुंजी / मान जोड़े को संभालने के लिए सीमित किया जा रहा है।

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

var testObject = { 'one': 1, 'two': 2, 'three': 3 };

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

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

console.log('retrievedObject: ', JSON.parse(retrievedObject));

159
निरीक्षण करते हैं कि किसी भी मेटाडेटा को हटा दिया जाएगा। आपको बस कुंजी-मूल्य जोड़े के साथ एक वस्तु मिलती है, इसलिए व्यवहार के साथ किसी भी वस्तु को फिर से बनाने की आवश्यकता है।
ओलिवोफ्रेन

5
@CMS सेट कर सकता है। यदि डेटा क्षमता से अधिक है तो कुछ अपवाद फेंक सकते हैं?
आशीष नेगी

3
... केवल गोलाकार संदर्भ वाली वस्तुओं पर लागू होता JSON.stringify()है, संदर्भित वस्तु को उसके पूर्ण "कंटेंट" (अनुमानित रूप से कड़े) में विस्तारित करता है , जिस वस्तु में हम कड़ाई करते हैं। देखें: stackoverflow.com/a/12659424/2044940
CodeManX

3
इस दृष्टिकोण के साथ समस्या प्रदर्शन के मुद्दे हैं, यदि आपको बड़े सरणियों या वस्तुओं को संभालना है।
मार्क

3
@oligofren सच है, लेकिन जैसा कि माजा ने सही ढंग से eval () => का सुझाव दिया है, यह एक अच्छा उपयोग है, आप आसानी से फ़ंक्शन कोड => इसे स्ट्रिंग के रूप में संग्रहीत कर सकते हैं और फिर eval () इसे वापस कर सकते हैं :)
jave.web

621

एक संस्करण पर एक मामूली सुधार :

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()होगा तुरंत लौट nullअगर keyसंग्रहण में नहीं है। यह भी एक SyntaxErrorअपवाद नहीं फेंक अगर valueहै ""(खाली स्ट्रिंग; JSON.parse()संभाल नहीं सकता है)।


48
मैं बस उपयोग को जल्दी से जोड़ना चाहता हूं क्योंकि यह मेरे लिए तुरंत स्पष्ट नहीं था: var userObject = { userId: 24, name: 'Jack Bauer' }; और इसे सेट करने के लिए localStorage.setObject('user', userObject); फिर इसे भंडारण से वापस प्राप्त करें userObject = localStorage.getObject('user'); आप चाहें तो वस्तुओं की एक सरणी भी स्टोर कर सकते हैं।
ज़ुलाउज़

8
यह सिर्फ बूलियन अभिव्यक्ति है। दूसरे भाग का मूल्यांकन केवल तभी किया जाता है जब एक को छोड़ा जाता है। उस स्थिति में संपूर्ण अभिव्यक्ति का परिणाम दाहिने भाग से होगा। यह लोकप्रिय टेक्निक है कि किस तरह से बूलियन एक्सप्रेशन का मूल्यांकन किया जाता है।
गुरिया

4
मुझे यहां स्थानीय चर और शॉर्टकट मूल्यांकन के बिंदु नहीं दिखते (मामूली प्रदर्शन सुधार एक तरफ)। यदि keyस्थानीय संग्रहण में नहीं है, तो window.localStorage.getItem(key)रिटर्न null- यह "अवैध पहुंच" अपवाद को नहीं फेंकता है - और साथ ही JSON.parse(null)रिटर्न null- यह या तो अपवाद नहीं फेंकता है, न तो क्रोमियम 21 में और न ही ES 5.1 खंड 15.12.2 , क्योंकि String(null) === "null"जो कर सकता है JSON शाब्दिक के रूप में व्याख्या की जाएगी ।
पॉइंटएर्स

6
स्थानीय संग्रहण में मान हमेशा आदिम स्ट्रिंग मान होते हैं। तो यह शॉर्टकट मूल्यांकन क्या करता है जब कोई ""पहले (खाली स्ट्रिंग) संग्रहीत करता है । क्योंकि यह टाइप-कन्वर्ट करता है falseऔर JSON.parse(""), जो SyntaxErrorअपवाद को फेंक देगा , इसे नहीं कहा जाता है।
प्वाइंटेडर्स

2
यह IE8 में काम नहीं करेगा, इसलिए यदि आपको इसका समर्थन करने की आवश्यकता है, तो पुष्ट उत्तर में फ़ंक्शन का उपयोग करना बेहतर है।
यहेजे

220

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

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

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

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


13
एक समारोह में सीएमएस को अप्रोच करना एक अच्छा विचार है, इसके लिए बस एक फीचर टेस्ट की जरूरत है: एक JSON.stringify के लिए, एक JSON.parse के लिए, और एक यह जांचने के लिए कि क्या लोकलस्टोरेज वास्तव में किसी ऑब्जेक्ट को सेट और अचीव कर सकता है। मेजबान वस्तुओं को संशोधित करना एक अच्छा विचार नहीं है; मैं इसे एक अलग विधि के रूप में देखना चाहूंगा और जैसा नहीं localStorage.setObject
गैरेट

4
यह getObject()एक फेंक देते हैं SyntaxError, तो संग्रहीत मूल्य है अपवाद ""क्योंकि, JSON.parse()कर सकते हैं कि संभाल नहीं। विवरण के लिए मेरा संपादन गुरिया के उत्तर में देखें।
प्वाइंटएडर्स

9
बस मेरे दो सेंट, लेकिन मुझे पूरा यकीन है कि इस तरह विक्रेता द्वारा प्रदान की गई वस्तुओं का विस्तार करना अच्छा नहीं है।
सेथेन


73

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

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

1
यह लगभग वही था जो मुझे चाहिए था। बस टिप्पणी से पहले अगर (मान == अशक्त) {वापसी झूठी} को जोड़ना था, अन्यथा स्थानीयस्टोरेज पर एक कुंजी के अस्तित्व की जांच करते समय त्रुटि हुई।
फ्रांसेस्को फ्रापुटी

2
यह वास्तव में बहुत अच्छा है। @FrancescoFraademyi से सहमत हों, यदि आपको अशक्त मानों के लिए कोई आवश्यकता है। मैंने भी जोड़ दिया || मान [0] == "[" "परीक्षण के मामले में वहाँ एक सरणी में।
रोब_जम्स

अच्छी बात है, मैं इसे संपादित करूँगा। हालाँकि आपको अशक्त भाग की आवश्यकता नहीं है, लेकिन यदि आप मुझे तीन === की सलाह देते हैं। यदि आप JSHint या JSLint का उपयोग करते हैं, तो आपको == का उपयोग करने के खिलाफ चेतावनी दी जाएगी।
एलेक्स ग्रांडे

3
और गैर-निनजा (मेरे जैसे) के लिए, क्या कोई इस उत्तर के लिए उपयोग उदाहरण प्रदान कर सकता है? क्या यह है data.set('username': 'ifedi', 'fullname': { firstname: 'Ifedi', lastname: 'Okonkwo'});:?
इदिदी ओकोनकोव

हाँ सचमुच! जब मैंने चम्मच खाने की अपनी इच्छा पर काबू पा लिया, तो मैंने परीक्षण करने के लिए कोड लिया, और इसे प्राप्त किया। मुझे लगता है कि यह उत्तर बहुत अच्छा है क्योंकि 1) स्वीकृत उत्तर के विपरीत, स्ट्रिंग डेटा पर कुछ जांच करने में समय लगता है, और 2) अगले एक के विपरीत, यह एक मूल वस्तु का विस्तार नहीं करता है।
इदिदी ओकोंकवो

64

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

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

//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 के लिए परिपत्र संरचना बदलना"JSON.stringify() फेंक देंगेTypeError । यदि परिपत्र संदर्भों को संग्रहीत किया जाना चाहिए, तो दूसरे पैरामीटर का 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;
    }
});

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

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


2
इसलिए, और कहने की जरूरत नहीं है - संग्रहण में डेटा संग्रहीत करना सरल डेटा की प्रतियों के एकमात्र आधार पर होना चाहिए । जीवित वस्तु नहीं।
रोको सी। बुल्जन

51

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

आप एक ऑब्जेक्ट सेट कर सकते हैं

$.jStorage.set(key, value)

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

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

2
@SuperUberDuper jStorage को प्रोटोटाइप, MooTools या jQuery की आवश्यकता है
JProgrammer

28

सिद्धांत रूप में, कार्यों के साथ वस्तुओं को संग्रहीत करना संभव है:

function store (a)
{
  var c = {f: {}, d: {}};
  for (var k in a)
  {
    if (a.hasOwnProperty(k) && typeof a[k] === 'function')
    {
      c.f[k] = encodeURIComponent(a[k]);
    }
  }

  c.d = a;
  var data = JSON.stringify(c);
  window.localStorage.setItem('CODE', data);
}

function restore ()
{
  var data = window.localStorage.getItem('CODE');
  data = JSON.parse(data);
  var b = data.d;

  for (var k in data.f)
  {
    if (data.f.hasOwnProperty(k))
    {
      b[k] = eval("(" + decodeURIComponent(data.f[k]) + ")");
    }
  }

  return b;
}

हालाँकि, फ़ंक्शन क्रमांकन / deserialization अविश्वसनीय है क्योंकि यह कार्यान्वयन-निर्भर है


1
फंक्शन सीरियलाइजेशन / डिसेरिएलाइज़ेशन अविश्वसनीय है क्योंकि यह कार्यान्वयन-निर्भर है । इसके अलावा, आप c.f[k] = escape(a[k]); यूनिकोड-से c.f[k] = encodeURIComponent(a[k]);और के eval('b.' + k + ' = ' + unescape(data.f[k]));साथ बदलना चाहते हैं b[k] = eval("(" + decodeURIComponent(data.f[k]) + ")");। कोष्ठकों की आवश्यकता होती है क्योंकि आपके कार्य को, यदि सही ढंग से क्रमबद्ध किया जाता है, तो अनाम होने की संभावना है, जो कि वैसा नहीं है जैसा कि एक मान्य / विवरण / है (इसलिए eval()) एक SyntaxErrorअपवाद को फेंक देगा )।
पॉइंटडायर्स

और typeofएक ऑपरेटर है , इसे ऐसा मत लिखो जैसे कि यह एक फ़ंक्शन था। बदलें typeof(a[k])के साथ typeof a[k]
10

अपने सुझावों को लागू करने और दृष्टिकोण की अविश्वसनीयता पर जोर देने के अलावा, मैंने निम्नलिखित कीड़े तय किए हैं: 1. सभी चर घोषित नहीं किए गए थे। 2. for- inअपने गुणों के लिए फ़िल्टर नहीं किया गया था। 3. कोड शैली, जिसमें संदर्भ भी शामिल है, असंगत था।
पॉइंटेडर्स

@PointedEars क्या व्यावहारिक अंतर बनाता है? युक्ति कहती है कि the use and placement of white space, line terminators, and semicolons within the representation String is implementation-dependent. मुझे कोई कार्यात्मक अंतर नहीं दिखता है।
माइकल

@ मिचेल ने आपके द्वारा उद्धृत किया गया भाग शुरू होता है Note *in particular* that …। लेकिन रिटर्न वैल्यू स्पेसिफिकेशन की शुरुआत रिटर्न वैल्यू के साथ होती An implementation-dependent representation of the function is returned. This representation has the syntax of a FunctionDeclaration.है function foo () {}- एक अनुरूप कार्यान्वयन को मानते हुए ।
प्वाइंटेडर्स

22

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

इसलिए यदि कोई अन्य व्यक्ति किसी सरणी के भीतर / पॉप / शिफ्ट आइटम को पुश करने में सक्षम होना चाहता है, और वे चाहते हैं कि यह सरणी लोकलस्टोरेज या वास्तव में सेशनस्टोर में संग्रहीत हो, तो आप यहां जाएं:

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

यह स्थानीयस्टोरेज या सेशनस्टोरेज में संग्रहित सरणियों में हेरफेर करने के तरीकों का एक बहुत ही आसान तरीका है, और यह आकर्षित होने की तुलना में बहुत अधिक क्रेडिट का हकदार है। @Andy लॉरेंज साझा करने के लिए समय निकालने के लिए धन्यवाद!
वेलोजेट


14

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


6

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

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

उदाहरण:

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

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


1
यह एक शानदार संसाधन है और बस मुझे जो चाहिए। मैं AngularJS के साथ Ionic ऐप कर रहा हूं, जहां मुझे लोकलस्टोरेज में कुछ जावास्क्रिप्ट ऑब्जेक्ट्स को सहेजने की आवश्यकता है और इस बिंदु तक मैं सिर्फ JSON.parse और JSON.stringify कर रहा हूं, और वे काम करते हैं, लेकिन यह सक्षम होने से थोड़ा अधिक बोझिल है बस इस तरह एक उपयोगिता का उपयोग करने के लिए। मैं इसे आजमाने जा रहा हूं।
नमुता

4

एक अन्य विकल्प मौजूदा प्लगइन का उपयोग करना होगा।

उदाहरण के लिए persisto एक ओपन सोर्स प्रोजेक्ट है, जो लोकलस्टोरेज / सेशनस्टोरेज को एक आसान इंटरफ़ेस प्रदान करता है और फॉर्म फील्ड्स (इनपुट, रेडियो बटन और चेकबॉक्स) के लिए दृढ़ता को स्वचालित करता है।

लगातार विशेषताएं

(अस्वीकरण: मैं लेखक हूं।)


अभी भी मेरे रीडमी पर काम कर रहा है, लेकिन मेरे संस्करण को jQuery की आवश्यकता नहीं है , क्योंकि ऐसा प्रतीत होता है कि यह जारी रहता है, लेकिन यह jQuery तत्व ऑब्जेक्ट्स से निपटने के लिए एक विकल्प प्रदान करता है। मैं निकट भविष्य में अधिक जोड़ दूंगा, क्योंकि मैं इसके साथ और अधिक काम करता हूं, ताकि इसे अलग-अलग jQuery ऑब्जेक्ट्स को संभालने और लगातार डेटा जैसी चीजों को बनाए रखने में मदद मिल सके। इसके अलावा, एक सरल समाधान प्रदान करने की कोशिश करने के लिए +1! इसके अलावा, यह सभी पारंपरिक तरीकों का उपयोग करता है localStroage; ऍक्स्प: var lsh = new localStorageHelper(); lsh.setItem('bob', 'bill'); इसके अलावा घटनाओं में शामिल हैं।
SpYk3HH

4

आप स्ट्रिंग के रूप में ऑब्जेक्ट्स को स्टोर करने के लिए ejson का उपयोग कर सकते हैं ।

EJSON अधिक प्रकार के समर्थन के लिए JSON का विस्तार है। यह सभी JSON- सुरक्षित प्रकारों का समर्थन करता है, साथ ही साथ:

  • दिनांक (जावास्क्रिप्ट Date)
  • बाइनरी (जावास्क्रिप्ट Uint8Arrayया EJSON.newBinary का परिणाम )
  • उपयोगकर्ता-परिभाषित प्रकार ( EJSON.addType देखें । उदाहरण के लिए, Mongo.ObjectID को इस तरह लागू किया गया है।)

सभी ईजेएसएन धारावाहिक भी मान्य JSON हैं। उदाहरण के लिए किसी तिथि और बाइनरी बफर वाली एक वस्तु को EJSON में क्रमबद्ध किया जाएगा:

{
  "d": {"$date": 1358205756553},
  "b": {"$binary": "c3VyZS4="}
}

यहाँ ejson का उपयोग करके मेरा लोकलस्टोरेज रैपर है

https://github.com/UziTech/storage.js

मैंने अपने आवरण में नियमित अभिव्यक्ति और कार्यों सहित कुछ प्रकार जोड़े


2

मैंने कोड की केवल 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


2

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

/**
 * 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");

2

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

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 का उपयोग नहीं करता है क्योंकि यह बड़ी वस्तुओं पर गलत और धीमा होगा। इसके बजाय, प्रत्येक टर्मिनल मान की अपनी स्थानीय प्रविष्टि प्रविष्टि होती है।

आप शायद अनुमान लगा सकते हैं कि मेरे पास राउबो के साथ कुछ करने के लिए हो सकता है।


1

यहाँ @danott द्वारा पोस्ट किए गए कोड के कुछ विस्तारित संस्करण हैं

यह लोकलस्टोरेज से डिलीट वैल्यू को भी लागू करेगा और दिखाता है कि इसके बजाय गेट्टर और सेटर लेयर को कैसे जोड़ा जाए

localstorage.setItem(preview, true)

तुम लिख सकते हो

config.preview = true

ठीक है यहाँ गए थे:

var PT=Storage.prototype

if (typeof PT._setItem >='u') PT._setItem = PT.setItem;
PT.setItem = function(key, value)
{
  if (typeof value >='u')//..ndefined
    this.removeItem(key)
  else
    this._setItem(key, JSON.stringify(value));
}

if (typeof PT._getItem >='u') PT._getItem = PT.getItem;
PT.getItem = function(key)
{  
  var ItemData = this._getItem(key)
  try
  {
    return JSON.parse(ItemData);
  }
  catch(e)
  {
    return ItemData;
  }
}

// Aliases for localStorage.set/getItem 
get =   localStorage.getItem.bind(localStorage)
set =   localStorage.setItem.bind(localStorage)

// Create ConfigWrapperObject
var config = {}

// Helper to create getter & setter
function configCreate(PropToAdd){
    Object.defineProperty( config, PropToAdd, {
      get: function ()      { return (  get(PropToAdd)      ) },
      set: function (val)   {           set(PropToAdd,  val ) }
    })
}
//------------------------------

// Usage Part
// Create properties
configCreate('preview')
configCreate('notification')
//...

// Config Data transfer
//set
config.preview = true

//get
config.preview

// delete
config.preview = undefined

अच्छी तरह से आप उपनाम भाग के साथ पट्टी कर सकते हैं .bind(...)। हालाँकि, मैंने इसे अभी से लागू कर दिया है क्योंकि इसके बारे में जानना वास्तव में अच्छा है। मुझे यह पता करने में घंटों लग गए कि एक साधारण get = localStorage.getItem;काम क्यों नहीं करता


1

मैंने एक चीज़ बनाई जो मौजूदा स्टोरेज ऑब्जेक्ट्स को नहीं तोड़ती है, लेकिन एक रैपर बनाती है ताकि आप जो चाहें कर सकें। परिणाम एक सामान्य वस्तु है, कोई विधि नहीं, किसी भी वस्तु की तरह पहुंच के साथ।

जो चीज मैंने बनाई।

यदि आप चाहते हैं कि 1 localStorageसंपत्ति जादू हो:

var prop = ObjectStorage(localStorage, 'prop');

यदि आपको कई चाहिए:

var storage = ObjectStorage(localStorage, ['prop', 'more', 'props']);

आप जो कुछ भी करते हैं prop, या उसके अंदर की वस्तुएं storageअपने आप बच जाएंगी localStorage। आप हमेशा एक वास्तविक वस्तु के साथ खेल रहे हैं, ताकि आप इस तरह से सामान कर सकें:

storage.data.list.push('more data');
storage.another.list.splice(1, 2, {another: 'object'});

और एक ट्रैक किए गए ऑब्जेक्ट के अंदर हर नई वस्तु स्वचालित रूप से ट्रैक की जाएगी।

बहुत बड़ा नकारात्मक पहलू: यह निर्भर करता है Object.observe()इसलिए इसमें बहुत सीमित ब्राउज़र समर्थन है। और ऐसा नहीं लगता कि यह जल्द ही फ़ायरफ़ॉक्स या एज के लिए आने वाला है।


1

आप स्ट्रिंग प्रारूप के बिना मुख्य मूल्य को संग्रहीत नहीं कर सकते ।

LocalStorage केवल कुंजी / मान के लिए स्ट्रिंग प्रारूप का समर्थन करता है।

यही कारण है कि आपको अपने डेटा को स्ट्रिंग में बदलना चाहिए जो भी ऐरे या ऑब्जेक्ट है

स्थानीयस्टोरेज में डेटा को स्टोर करने के लिए सबसे पहले JSON.stringify () मेथड का उपयोग करके इसे कड़ा करें

var myObj = [{name:"test", time:"Date 2017-02-03T08:38:04.449Z"}];
localStorage.setItem('item', JSON.stringify(myObj));

फिर जब आप डेटा पुनः प्राप्त करना चाहते हैं, तो आपको स्ट्रिंग को फिर से ऑब्जेक्ट करने के लिए पार्स करने की आवश्यकता होती है।

var getObj = JSON.parse(localStorage.getItem('item'));

आशा है ये मदद करेगा।


0

किसी ऑब्जेक्ट को संग्रहीत करने के लिए, आप एक अक्षर बना सकते हैं जिसका उपयोग आप किसी ऑब्जेक्ट को स्ट्रिंग से ऑब्जेक्ट पर लाने के लिए कर सकते हैं (इसका कोई मतलब नहीं हो सकता है)। उदाहरण के लिए

var obj = {a: "lol", b: "A", c: "hello world"};
function saveObj (key){
    var j = "";
    for(var i in obj){
        j += (i+"|"+obj[i]+"~");
    }
    localStorage.setItem(key, j);
} // Saving Method
function getObj (key){
    var j = {};
    var k = localStorage.getItem(key).split("~");
    for(var l in k){
        var m = k[l].split("|");
        j[m[0]] = m[1];
    }
    return j;
}
saveObj("obj"); // undefined
getObj("obj"); // {a: "lol", b: "A", c: "hello world"}

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


0

मुझे चक्रीय संदर्भ वाली वस्तुओं के साथ काम करने का एक तरीका मिला।

चलो चक्रीय संदर्भों के साथ एक वस्तु बनाते हैं।

obj = {
    L: {
        L: { v: 'lorem' },
        R: { v: 'ipsum' }
    },
    R: {
        L: { v: 'dolor' },
        R: {
            L: { v: 'sit' },
            R: { v: 'amet' }
        }
    }
}
obj.R.L.uncle = obj.L;
obj.R.R.uncle = obj.L;
obj.R.R.L.uncle = obj.R.L;
obj.R.R.R.uncle = obj.R.L;
obj.L.L.uncle = obj.R;
obj.L.R.uncle = obj.R;

JSON.stringifyसर्कुलर रेफरेंस के कारण हम यहां नहीं कर सकते ।

circularUncle

LOCALSTORAGE.CYCLICJSONहै .stringifyऔर .parseसामान्य की तरह JSON, लेकिन परिपत्र संदर्भ के साथ वस्तुओं के साथ काम करता है। ("वर्क्स" का अर्थ पार्स (स्ट्रिफ़िज़ (obj)) और obj गहरे बराबर हैं और 'आंतरिक समानताएँ' के समान सेट हैं)

लेकिन हम सिर्फ शॉर्टकट का उपयोग कर सकते हैं:

LOCALSTORAGE.setObject('latinUncles', obj)
recovered = LOCALSTORAGE.getObject('latinUncles')

फिर, recoveredनिम्नलिखित अर्थों में, "वही" को मानना ​​होगा:

[
obj.L.L.v === recovered.L.L.v,
obj.L.R.v === recovered.L.R.v,
obj.R.L.v === recovered.R.L.v,
obj.R.R.L.v === recovered.R.R.L.v,
obj.R.R.R.v === recovered.R.R.R.v,
obj.R.L.uncle === obj.L,
obj.R.R.uncle === obj.L,
obj.R.R.L.uncle === obj.R.L,
obj.R.R.R.uncle === obj.R.L,
obj.L.L.uncle === obj.R,
obj.L.R.uncle === obj.R,
recovered.R.L.uncle === recovered.L,
recovered.R.R.uncle === recovered.L,
recovered.R.R.L.uncle === recovered.R.L,
recovered.R.R.R.uncle === recovered.R.L,
recovered.L.L.uncle === recovered.R,
recovered.L.R.uncle === recovered.R
]

यहाँ का कार्यान्वयन है LOCALSTORAGE

LOCALSTORAGE = (function(){
  "use strict";
  var ignore = [Boolean, Date, Number, RegExp, String];
  function primitive(item){
    if (typeof item === 'object'){
      if (item === null) { return true; }
      for (var i=0; i<ignore.length; i++){
        if (item instanceof ignore[i]) { return true; }
      }
      return false;
    } else {
      return true;
    }
  }
  function infant(value){
    return Array.isArray(value) ? [] : {};
  }
  function decycleIntoForest(object, replacer) {
    if (typeof replacer !== 'function'){
      replacer = function(x){ return x; }
    }
    object = replacer(object);
    if (primitive(object)) return object;
    var objects = [object];
    var forest  = [infant(object)];
    var bucket  = new WeakMap(); // bucket = inverse of objects 
    bucket.set(object, 0);    
    function addToBucket(obj){
      var result = objects.length;
      objects.push(obj);
      bucket.set(obj, result);
      return result;
    }
    function isInBucket(obj){ return bucket.has(obj); }
    function processNode(source, target){
      Object.keys(source).forEach(function(key){
        var value = replacer(source[key]);
        if (primitive(value)){
          target[key] = {value: value};
        } else {
          var ptr;
          if (isInBucket(value)){
            ptr = bucket.get(value);
          } else {
            ptr = addToBucket(value);
            var newTree = infant(value);
            forest.push(newTree);
            processNode(value, newTree);
          }
          target[key] = {pointer: ptr};
        }
      });
    }
    processNode(object, forest[0]);
    return forest;
  };
  function deForestIntoCycle(forest) {
    var objects = [];
    var objectRequested = [];
    var todo = [];
    function processTree(idx) {
      if (idx in objects) return objects[idx];
      if (objectRequested[idx]) return null;
      objectRequested[idx] = true;
      var tree = forest[idx];
      var node = Array.isArray(tree) ? [] : {};
      for (var key in tree) {
        var o = tree[key];
        if ('pointer' in o) {
          var ptr = o.pointer;
          var value = processTree(ptr);
          if (value === null) {
            todo.push({
              node: node,
              key: key,
              idx: ptr
            });
          } else {
            node[key] = value;
          }
        } else {
          if ('value' in o) {
            node[key] = o.value;
          } else {
            throw new Error('unexpected')
          }
        }
      }
      objects[idx] = node;
      return node;
    }
    var result = processTree(0);
    for (var i = 0; i < todo.length; i++) {
      var item = todo[i];
      item.node[item.key] = objects[item.idx];
    }
    return result;
  };
  var console = {
    log: function(x){
      var the = document.getElementById('the');
      the.textContent = the.textContent + '\n' + x;
	},
	delimiter: function(){
      var the = document.getElementById('the');
      the.textContent = the.textContent +
		'\n*******************************************';
	}
  }
  function logCyclicObjectToConsole(root) {
    var cycleFree = decycleIntoForest(root);
    var shown = cycleFree.map(function(tree, idx) {
      return false;
    });
    var indentIncrement = 4;
    function showItem(nodeSlot, indent, label) {
      var leadingSpaces = ' '.repeat(indent);
      var leadingSpacesPlus = ' '.repeat(indent + indentIncrement);
      if (shown[nodeSlot]) {
        console.log(leadingSpaces + label + ' ... see above (object #' + nodeSlot + ')');
      } else {
        console.log(leadingSpaces + label + ' object#' + nodeSlot);
        var tree = cycleFree[nodeSlot];
        shown[nodeSlot] = true;
        Object.keys(tree).forEach(function(key) {
          var entry = tree[key];
          if ('value' in entry) {
            console.log(leadingSpacesPlus + key + ": " + entry.value);
          } else {
            if ('pointer' in entry) {
              showItem(entry.pointer, indent + indentIncrement, key);
            }
          }
        });
      }
    }
	console.delimiter();
    showItem(0, 0, 'root');
  };
  function stringify(obj){
    return JSON.stringify(decycleIntoForest(obj));
  }
  function parse(str){
    return deForestIntoCycle(JSON.parse(str));
  }
  var CYCLICJSON = {
    decycleIntoForest: decycleIntoForest,
    deForestIntoCycle : deForestIntoCycle,
    logCyclicObjectToConsole: logCyclicObjectToConsole,
    stringify : stringify,
    parse : parse
  }
  function setObject(name, object){
    var str = stringify(object);
    localStorage.setItem(name, str);
  }
  function getObject(name){
    var str = localStorage.getItem(name);
    if (str===null) return null;
    return parse(str);
  }
  return {
    CYCLICJSON : CYCLICJSON,
    setObject  : setObject,
    getObject  : getObject
  }
})();
obj = {
	L: {
		L: { v: 'lorem' },
		R: { v: 'ipsum' }
	},
	R: {
		L: { v: 'dolor' },
		R: {
			L: { v: 'sit' },
			R: { v: 'amet' }
		}
	}
}
obj.R.L.uncle = obj.L;
obj.R.R.uncle = obj.L;
obj.R.R.L.uncle = obj.R.L;
obj.R.R.R.uncle = obj.R.L;
obj.L.L.uncle = obj.R;
obj.L.R.uncle = obj.R;

// LOCALSTORAGE.setObject('latinUncles', obj)
// recovered = LOCALSTORAGE.getObject('latinUncles')
// localStorage not available inside fiddle ):
LOCALSTORAGE.CYCLICJSON.logCyclicObjectToConsole(obj)
putIntoLS = LOCALSTORAGE.CYCLICJSON.stringify(obj);
recovered = LOCALSTORAGE.CYCLICJSON.parse(putIntoLS);
LOCALSTORAGE.CYCLICJSON.logCyclicObjectToConsole(recovered);

var the = document.getElementById('the');
the.textContent = the.textContent + '\n\n' +
JSON.stringify(
[
obj.L.L.v === recovered.L.L.v,
obj.L.R.v === recovered.L.R.v,
obj.R.L.v === recovered.R.L.v,
obj.R.R.L.v === recovered.R.R.L.v,
obj.R.R.R.v === recovered.R.R.R.v,
obj.R.L.uncle === obj.L,
obj.R.R.uncle === obj.L,
obj.R.R.L.uncle === obj.R.L,
obj.R.R.R.uncle === obj.R.L,
obj.L.L.uncle === obj.R,
obj.L.R.uncle === obj.R,
recovered.R.L.uncle === recovered.L,
recovered.R.R.uncle === recovered.L,
recovered.R.R.L.uncle === recovered.R.L,
recovered.R.R.R.uncle === recovered.R.L,
recovered.L.L.uncle === recovered.R,
recovered.L.R.uncle === recovered.R
]
)
<pre id='the'></pre>


-2

localStorage.setItem ('उपयोगकर्ता', JSON.stringify (उपयोगकर्ता));

फिर इसे स्टोर से पुनः प्राप्त करने और फिर से किसी ऑब्जेक्ट में बदलने के लिए:

var उपयोगकर्ता = JSON.parse (localStorage.getItem ('उपयोगकर्ता'));

यदि हमें स्टोर की सभी प्रविष्टियों को हटाने की आवश्यकता है, तो हम बस यह कर सकते हैं:

localStorage.clear ();


3
यह 10 साल पुराना सवाल है। क्या आपको लगता है कि आपका उत्तर कुछ भी जोड़ता है जो पहले से ही अन्य उत्तरों से कवर नहीं है?
क्रिस्टोफर जॉनसन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.