บันทึกวัตถุ Javascript ใน sessionStorage


152

SessionStorage และ LocalStorage ช่วยให้สามารถบันทึกคู่คีย์ / ค่าในเว็บเบราว์เซอร์ ค่าต้องเป็นสตริงและการบันทึกอ็อบเจ็กต์ js นั้นไม่สำคัญ

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

ทุกวันนี้คุณสามารถหลีกเลี่ยงข้อ จำกัด นี้ได้ด้วยการทำให้เป็นออบเจ็กต์เป็น JSON จากนั้นจึงยกเลิกการซีเรียลไลซ์เพื่อกู้คืนออบเจ็กต์ แต่ API การจัดเก็บข้อมูลผ่านsetItemและgetItemวิธีการเสมอ

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

ฉันสามารถหลีกเลี่ยงข้อ จำกัด นี้ได้หรือไม่?

ฉันแค่อยากจะทำอะไรแบบนี้:

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

ฉันได้ลองdefineGetterและdefineSetterวิธีในการสกัดกั้นการโทร แต่เป็นงานที่น่าเบื่อเพราะฉันต้องกำหนดคุณสมบัติทั้งหมดและเป้าหมายของฉันคือไม่ทราบคุณสมบัติในอนาคต


1
ฉันคิดว่าตัวเอง ฉันคิดว่าผู้คนจำนวนมากมี แต่ฉันไม่คิดว่าวิธีการทะเยอทะยานและตัวตั้งค่าเป็นภาระมากเกินไป BTW; คุณสามารถทำให้เป็นอันดับและแยกวิเคราะห์ด้วย JavaScript และ MS ในที่สุดก็รองรับวัตถุมาตรฐานเช่นเดียวกับคนอื่น ๆ วันที่ต้องการแพคเกจอย่าง JSON และ jQuery กำลังจะสิ้นสุดลงอย่างรวดเร็ว
Roger F. Gay

1
ฉันเดาว่าฉันไม่เห็นข้อ จำกัด อาจดูเหมือน overkill ในการใช้ JSON.stringify และ JSON.parse หากคุณมีเพียงวัตถุที่ไม่สำคัญ แต่ถ้าคุณมีวัตถุข้อมูลขนาดใหญ่แม้แต่สองวิธีก็กำลังทำงานให้คุณมาก
Robusto

5
"ฉันสามารถหลีกเลี่ยงข้อ จำกัด นี้ได้หรือไม่" ดูเหมือนคำถาม
sonicblis

1
มีข้อ จำกัด หรือไม่คำถามนี้ช่วยฉันแก้ปัญหาได้ขอบคุณ
Matt West

คำตอบ:


19

คุณสามารถใช้ accessors ที่ได้รับจาก Web Storage API หรือคุณสามารถเขียน wrapper / adapter จากปัญหาที่ระบุไว้ของคุณด้วย defineGetter / defineSetter ดูเหมือนว่าการเขียน wrapper / adapter นั้นใช้งานได้มากเกินไปสำหรับคุณ

ฉันไม่รู้จะบอกคุณตรงไหน บางทีคุณอาจประเมินความเห็นของคุณว่าอะไรคือ "ข้อ จำกัด ที่ไร้สาระ" Web Storage API เป็นที่เก็บคีย์ / ค่า


8
ขออภัยถ้าฉันใช้คำที่ไม่เหมาะสมกับ 'ไร้สาระ' แทนที่ด้วย 'อาจจะน่าสนใจมาก' ฉันคิดว่า webStorage เป็นหนึ่งในการปรับปรุงที่น่าตื่นเต้นที่สุดของเว็บใหม่ แต่บันทึกเฉพาะสตริงในคีย์แผนที่ค่าฉันคิดว่าเป็นข้อ จำกัด ดูเหมือนว่าจะเป็นภาคต่อของคุกกี้ ฉันรู้ว่าการจัดเก็บเป็นข้อกำหนดที่ไม่เพียง แต่สำหรับภาษาจาวาสคริปต์ แต่วัตถุที่เป็นอนุกรมอาจเป็นการปรับปรุงที่น่าสนใจ คุณคิดอย่างไร?
Ferran Basora

2
หาก JSON ไม่เพียงพอคุณสามารถเขียนวิธีการทำให้เป็นอันดับวัตถุของคุณเองได้ตลอดเวลา
Ryan Olds

110

คุณไม่สามารถ 'stringify' วัตถุของคุณ ... จากนั้นใช้sessionStorage.setItem()ในการจัดเก็บการเป็นตัวแทนสตริงของวัตถุของคุณ ... แล้วเมื่อคุณต้องการมันsessionStorage.getItem()และจากนั้นใช้$.parseJSON()เพื่อดึงมันออกมา?

ตัวอย่างการทำงานhttp://jsfiddle.net/pKXMa/


มันใช้งานได้สำหรับฉัน ฉันได้รับวัตถุ Json ที่ทำงานหลังจากโทร $ .parseJSON ()
Olafur Tryggvason

บางระบบเช่นการรับรองความถูกต้องของ Web Api ส่งคืนวัตถุในรูปแบบของ Object {propertyOneWithoutQuotes: "<value1>", ... propertyNWithoutQuotes: "<valueN>"} ซึ่งต้องผ่าน "stringify" หากมีหลายแหล่งควรใช้ stringify เพื่อสร้างมาตรฐานให้กับข้อมูล
Jelgab

นี่เป็นคำตอบที่ดีมาก มันเป็นการดีที่จะใช้ JSON.stringify () เพื่อทำให้เป็นอันดับวัตถุและเก็บใน sessionStorage จากนั้นจะใช้ $ .parseJSON () เพื่อยกเลิกการทำให้เป็นสตริงสตริงเพื่อรับวัตถุ
Thomas.Benz

102

การแก้ปัญหาคือการทำให้วัตถุแตกก่อนที่จะเรียก setItem บน sessionStorage

var user = {'name':'John'};
sessionStorage.setItem('user', JSON.stringify(user));
var obj = JSON.parse(sessionStorage.user);

ขอบคุณที่ไม่เชื่อมโยงโซลูชัน
Luc-Olsthoorn

12

นี่เป็นโซลูชันแบบไดนามิกที่ทำงานกับทุกประเภทของค่ารวมถึงวัตถุ:

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

จากนั้น:

const session = new Session();

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

5

ใช้กรณี:

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

4
ฉันคิดว่าหนึ่งในแนวปฏิบัติที่ดีที่สุดในจาวาสคริปต์คือไม่ใช่วัตถุต้นแบบที่คุณไม่ได้เป็นเจ้าของ การใช้ Storage.prototype.setObj ดูเหมือนจะเป็นความคิดที่ไม่ดี
britztopher

3
เพียงแค่เพิ่มข้อผูกพัน .. ตรวจสอบให้แน่ใจว่าคุณไม่ได้เพิ่มรหัสต้นแบบนี้ - และพึ่งพามันโดยเฉพาะ - โดยไม่ตรวจสอบก่อนว่าเบราว์เซอร์รองรับการจัดเก็บ:if (typeof (Storage) !== "undefined"){ /* browser supports it */ }
JoeBrockhaus

4

ที่จัดเก็บข้อมูลเซสชันไม่สามารถรองรับวัตถุที่กำหนดเองได้เนื่องจากอาจมีฟังก์ชั่นตัวอักษร (การปิดอ่าน) ซึ่งไม่สามารถสร้างขึ้นใหม่ได้หลังจากที่โหลดหน้าเว็บซ้ำ



2

คุณยังสามารถใช้ไลบรารีร้านค้าซึ่งทำหน้าที่ให้กับคุณด้วยความสามารถของ crossbrowser

ตัวอย่าง:

// 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)
})

0

คุณสามารถสร้างวิธีการ 2 แบบสำหรับการบันทึกและดึงข้อมูลวัตถุจากที่จัดเก็บข้อมูลเซสชัน

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

ใช้อย่างนี้: - รับวัตถุแก้ไขข้อมูลบางส่วนแล้วบันทึกกลับ

var obj = getSession();

obj.newProperty = "Prod"

saveSession(obj);
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.