متى تنتهي صلاحية العناصر في HTML5 التخزين المحلي؟

StackOverflow https://stackoverflow.com/questions/2326943

  •  22-09-2019
  •  | 
  •  

سؤال

إلى متى يتم تخزين البيانات في LocalStorage (كجزء من تخزين DOM في HTML5)؟ هل يمكنني ضبط وقت انتهاء الصلاحية للبيانات التي وضعتها في LocalStorage؟

هل كانت مفيدة؟

المحلول

لا يمكن تحديد انتهاء الصلاحية. الأمر متروك تمامًا للمستخدم.

https://developer.mozilla.org/en-us/docs/web/api/window/localstorage

بالطبع ، من الممكن أن لا يكون هناك شيء ما يخزنه التطبيق على العميل لاحقًا. يمكن للمستخدم التخلص بشكل صريح من التخزين المحلي ، أو قد يواجه المتصفح اعتبارات الفضاء. من الجيد البرمجة بشكل دفاعي. بشكل عام ، تظل الأمور "إلى الأبد" بناءً على بعض التعريف العملي لتلك الكلمة.

تعديل - من الواضح أن التطبيق الخاص بك يمكن أن يزيل الأشياء بنشاط إذا قرر أن يكون قديمًا جدًا. أي أنه يمكنك تضمين نوع من الطابع الزمني بشكل صريح فيما قمت بحفظه ، ثم استخدام ذلك لاحقًا لتحديد ما إذا كان ينبغي مسح المعلومات أم لا.

نصائح أخرى

أود أن أقترح تخزين الطابع الزمني في هدف يمكنك تخزينها في LocalStorage

var object = {value: "value", timestamp: new Date().getTime()}
localStorage.setItem("key", JSON.stringify(object));

يمكنك تحليل الكائن والحصول على الطابع الزمني ومقارنة التاريخ الحالي ، وإذا لزم الأمر ، قم بتحديث قيمة الكائن.

var object = JSON.parse(localStorage.getItem("key")),
    dateString = object.timestamp,
    now = new Date().getTime().toString();

compareTime(dateString, now); //to implement

يمكنك استخدام lscache. إنه يتعامل مع هذا لك تلقائيًا ، بما في ذلك الحالات التي يتجاوز فيها حجم التخزين الحد. إذا حدث ذلك ، فإنه يبدأ في تقليم العناصر التي هي الأقرب إلى انتهاء صلاحيتها المحددة.

من readme:

lscache.set

Stores the value in localStorage. Expires after specified number of minutes.

Arguments
key (string)
value (Object|string)
time (number: optional)

هذا هو الفرق الحقيقي الوحيد بين طرق التخزين العادية. الحصول على ، إزالة ، وما إلى ذلك العمل كما هو.

إذا لم تكن بحاجة إلى الكثير من الوظائف ، فيمكنك ببساطة تخزين طابع زمني مع القيمة (عبر JSON) والتحقق من ذلك للاضطلاع.

من الجدير بالذكر أن هناك سببًا وجيهًا لترك التخزين المحلي للمستخدم. لكن أشياء مثل LSCACHE تكون في متناول يدي عندما تحتاج إلى تخزين بيانات مؤقتة للغاية.

برينر فيريرا ، جلبت نقطة جيدة: تخزين مفتاح الأخوة حيث توجد معلومات انتهاء الصلاحية. من هنا، إذا كان لديك كمية كبيرة من المفاتيح ، أو إذا كانت قيمك كائنات JSON كبيرة, ، لا تحتاج إلى تحليلهم للوصول إلى الطابع الزمني.

هنا يتبع نسخة محسنة:

 /*  removeStorage: removes a key from localStorage and its sibling expiracy key
    params:
        key <string>     : localStorage key to remove
    returns:
        <boolean> : telling if operation succeeded
 */
 function removeStorage(name) {
    try {
        localStorage.removeItem(name);
        localStorage.removeItem(name + '_expiresIn');
    } catch(e) {
        console.log('removeStorage: Error removing key ['+ key + '] from localStorage: ' + JSON.stringify(e) );
        return false;
    }
    return true;
}
/*  getStorage: retrieves a key from localStorage previously set with setStorage().
    params:
        key <string> : localStorage key
    returns:
        <string> : value of localStorage key
        null : in case of expired key or failure
 */
function getStorage(key) {

    var now = Date.now();  //epoch time, lets deal only with integer
    // set expiration for storage
    var expiresIn = localStorage.getItem(key+'_expiresIn');
    if (expiresIn===undefined || expiresIn===null) { expiresIn = 0; }

    if (expiresIn < now) {// Expired
        removeStorage(key);
        return null;
    } else {
        try {
            var value = localStorage.getItem(key);
            return value;
        } catch(e) {
            console.log('getStorage: Error reading key ['+ key + '] from localStorage: ' + JSON.stringify(e) );
            return null;
        }
    }
}
/*  setStorage: writes a key into localStorage setting a expire time
    params:
        key <string>     : localStorage key
        value <string>   : localStorage value
        expires <number> : number of seconds from now to expire the key
    returns:
        <boolean> : telling if operation succeeded
 */
function setStorage(key, value, expires) {

    if (expires===undefined || expires===null) {
        expires = (24*60*60);  // default: seconds for 1 day
    } else {
        expires = Math.abs(expires); //make sure it's positive
    }

    var now = Date.now();  //millisecs since epoch time, lets deal only with integer
    var schedule = now + expires*1000; 
    try {
        localStorage.setItem(key, value);
        localStorage.setItem(key + '_expiresIn', schedule);
    } catch(e) {
        console.log('setStorage: Error setting key ['+ key + '] in localStorage: ' + JSON.stringify(e) );
        return false;
    }
    return true;
}

في حين أن التخزين المحلي لا يوفر آلية انتهاء الصلاحية ، فإن ملفات تعريف الارتباط تفعل. ببساطة يوفر إقران مفتاح التخزين المحلي مع ملف تعريف الارتباط طريقة سهلة لضمان تحديث التخزين المحلي مع نفس معلمات انتهاء الصلاحية مثل ملف تعريف الارتباط.

مثال في jQuery:

if (!$.cookie('your_key') || !localStorage.getItem('your_key')) {
    //get your_data from server, then...
    localStorage.setItem('your_key', 'your_data' );
    $.cookie('your_key', 1);
} else {
    var your_data = localStorage.getItem('your_key');
}
// do stuff with your_data

هذا المثال يعين ملف تعريف الارتباط مع المعلمة الافتراضية لانتهاء عند إغلاق المتصفح. وبالتالي ، عندما يتم إغلاق المتصفح وإعادة فتحه ، يتم تحديث متجر البيانات المحلي لـ _data عن طريق مكالمة من جانب الخادم.

لاحظ أن هذا ليس هو نفسه بالضبط إزالة متجر البيانات المحلي ، بدلاً من ذلك ، يقوم بتحديث متجر البيانات المحلي كلما انتهت صلاحية ملف تعريف الارتباط. ومع ذلك ، إذا كان هدفك الرئيسي هو أن تكون قادرًا على تخزين أكثر من 4K عميل (قيود حجم ملفات تعريف الارتباط) ، فإن هذا الاقتران من ملفات تعريف الارتباط والتخزين المحلي سيساعدك على تحقيق حجم تخزين أكبر باستخدام نفس معلمات انتهاء الصلاحية مثل ملف تعريف الارتباط .

الموصى بها بشدة للاستخدام SessionStorage

  • هو نفسه التخزين المحلي لكن تدمير عندما دمرت الجلسة / المتصفح
  • يعد SessionStorage مفيدًا أيضًا لتقليل حركة مرور الشبكة مقابل ملف تعريف الارتباط

لاستخدام القيمة المحددة

sessionStorage.setItem("key","my value");

للحصول على استخدام القيمة

var value = sessionStorage.getItem("key");

انقر هنا لعرض API

جميع الطرق للمجموعة

  sessionStorage.key = "my val";
  sessionStorage["key"] = "my val";
  sessionStorage.setItem("key","my value");

جميع الطرق للحصول على

  var value = sessionStorage.key;
  var value = sessionStorage["key"];
  var value = sessionStorage.getItem("key");

يتم التحكم في دورة الحياة بواسطة التطبيق/المستخدم.

من اساسي:

يجب أن ينتهي وكلاء المستخدمين من مناطق التخزين المحلية فقط لأسباب أمنية أو عند طلب ذلك من قبل المستخدم. يجب على وكلاء المستخدمين دائمًا تجنب حذف البيانات أثناء تشغيل البرنامج النصي الذي يمكنه الوصول إلى هذه البيانات.

من مسودة W3C:

يجب أن ينتهي وكلاء المستخدمين من مناطق التخزين المحلية فقط لأسباب أمنية أو عند طلب ذلك من قبل المستخدم. يجب على وكلاء المستخدمين دائمًا تجنب حذف البيانات أثناء تشغيل البرنامج النصي الذي يمكنه الوصول إلى هذه البيانات.

ستحتاج إلى إجراء تحديثاتك على الجدول الزمني الخاص بك باستخدام SetItem (المفتاح ، القيمة) ؛ سيؤدي ذلك إلى إضافة أو تحديث المفتاح المحدد بالبيانات الجديدة.

// Functions
function removeHtmlStorage(name) {
    localStorage.removeItem(name);
    localStorage.removeItem(name+'_time');
}

function setHtmlStorage(name, value, expires) {

    if (expires==undefined || expires=='null') { var expires = 3600; } // default: 1h

    var date = new Date();
    var schedule = Math.round((date.setSeconds(date.getSeconds()+expires))/1000);

    localStorage.setItem(name, value);
    localStorage.setItem(name+'_time', schedule);
}

function statusHtmlStorage(name) {

    var date = new Date();
    var current = Math.round(+date/1000);

    // Get Schedule
    var stored_time = localStorage.getItem(name+'_time');
    if (stored_time==undefined || stored_time=='null') { var stored_time = 0; }

    // Expired
    if (stored_time < current) {

        // Remove
        removeHtmlStorage(name);

        return 0;

    } else {

        return 1;
    }
}

// Status
var cache_status = statusHtmlStorage('cache_name');

// Has Data
if (cache_status == 1) {

    // Get Cache
    var data = localStorage.getItem('cache_name');
    alert(data);

// Expired or Empty Cache
} else {

    // Get Data
    var data = 'Pay in cash :)';
    alert(data);

    // Set Cache (30 seconds)
    if (cache) { setHtmlStorage('cache_name', data, 30); }

}

إذا كان شخص ما يستخدم jstorage plugin من jQuery ، فيمكن إضافة انتهاء الصلاحية مع وظيفة setTTL إذا كان jstorage البرنامج المساعد

$.jStorage.set('myLocalVar', "some value");
$.jStorage.setTTL("myLocalVar", 24*60*60*1000); // 24 Hr.

إذا كان أي شخص لا يزال يبحث عن حل سريع ولا يريد تبعيات مثل jQuery وما إلى ذلك ، فقد كتبت lib مصغرة تضيف انتهاء صلاحية التخزين المحلي / الجلسة / المخصصة ، يمكنك العثور عليها مع المصدر هنا:

https://github.com/ronenness/expiredStorage

حل بديل باستخدام الزاوي والموحدة:

angular.module('app').service('cacheService', function() {

  return {
    set: function(key, value, expireTimeInSeconds) {
      return localforage.setItem(key, {
        data: value,
        timestamp: new Date().getTime(),
        expireTimeInMilliseconds: expireTimeInSeconds * 1000
      })
    },
    get: function(key) {
      return localforage.getItem(key).then(function(item) {
        if(!item || new Date().getTime() > (item.timestamp + item.expireTimeInMilliseconds)) {
          return null
        } else {
          return item.data
        }
      })
    }
  }

})

نهج @Sebarmeli هو الأفضل في رأيي ، ولكن إذا كنت تريد فقط أن تستمر البيانات لحياة الجلسة بعد ذلك sessionStorage ربما يكون خيارًا أفضل:

هذا كائن عالمي (SessionStorage) يحافظ على منطقة تخزين متاحة طوال فترة جلسة الصفحة. تستمر جلسة الصفحة طالما أن المتصفح مفتوح وينجى على إعادة تحميل الصفحة والاستعادة. يؤدي فتح صفحة في علامة تبويب أو نافذة جديدة إلى بدء جلسة جديدة.

MDN: SessionStorage

لصالح الباحثين:

مثل فرناندو ، لم أكن أرغب في إضافة حمولة من JSON عندما كانت القيم المخزنة بسيطة. كنت بحاجة فقط لتتبع بعض تفاعل واجهة المستخدم والحفاظ على البيانات ذات صلة (على سبيل المثال كيف استخدم المستخدم موقع التجارة الإلكترونية قبل التحقق).

لن يستوفي هذا معايير الجميع ، ولكن نأمل أن تكون نسخة سريعة+لصق معجون لشخص ما وحفظ إضافة lib آخر.

ملاحظة: لن يكون هذا جيدًا إذا كنت بحاجة إلى استرداد العناصر بشكل فردي.

// Addition
if(window.localStorage){
    localStorage.setItem('myapp-' + new Date().getTime(), 'my value');
}

// Removal of all expired items
if(window.localStorage){

    // two mins - (1000 * 60 * 20) would be 20 mins
    var expiryTime = new Date().getTime() - (1000 * 60 * 2);

    var deleteRows = [];
    for(var i=0; i < localStorage.length; i++){
        var key = localStorage.key(i);
        var partsArray = key.split('-');
        // The last value will be a timestamp
        var lastRow = partsArray[partsArray.length - 1];

        if(lastRow && parseInt(lastRow) < expiryTime){
            deleteRows.push(key);
        }
    }
    // delete old data
    for(var j=0; j < deleteRows.length; j++){
        localStorage.removeItem(deleteRows[j]);
    }
}

يمكنك تجربة هذا.

var hours = 24; // Reset when storage is more than 24hours
var now = new Date().getTime();
var setupTime = localStorage.getItem('setupTime');
if (setupTime == null) {
     localStorage.setItem('setupTime', now)
} else {
    if(now-setupTime > hours*60*60*1000) {
         localStorage.clear()
         localStorage.setItem('setupTime', now);
    }
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top