Khi nào các mục trong bộ nhớ cục bộ HTML5 hết hạn?


336

Dữ liệu được lưu trữ trong localStorage trong bao lâu (như một phần của Lưu trữ DOM trong HTML5)? Tôi có thể đặt thời gian hết hạn cho dữ liệu mà tôi đã đặt vào localStorage không?


3
không sử dụng localStorage nếu có thể vì không bao giờ hết hạn tự động, ở đó bạn có thể sử dụng sessionStorage, nó thích hợp hơn
Dharmendrasinh Chudasama

Câu trả lời:


215

Không thể chỉ định hết hạn. Nó hoàn toàn phụ thuộc vào người dùng.

https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage

Tất nhiên, có thể thứ gì đó mà ứng dụng của bạn lưu trữ trên máy khách có thể không xuất hiện sau đó. Người dùng rõ ràng có thể thoát khỏi bộ nhớ cục bộ hoặc trình duyệt có thể chạy vào các cân nhắc về không gian. Thật tốt khi lập trình phòng thủ. Tuy nhiên, nói chung mọi thứ vẫn "mãi mãi" dựa trên một số định nghĩa thực tế của từ đó.

chỉnh sửa - rõ ràng, ứng dụng của riêng bạn có thể chủ động xóa nội dung nếu nó quyết định nó quá cũ. Đó là, bạn có thể bao gồm một cách rõ ràng một số loại dấu thời gian trong những gì bạn đã lưu và sau đó sử dụng nó sau đó để quyết định xem có nên xóa thông tin hay không.


1
Vì vậy, người dùng có thể tin tưởng vào dữ liệu có sẵn sau một năm không? Nhà phát triển có thể tin tưởng vào dữ liệu có sẵn trừ khi người dùng xóa nó một cách rõ ràng không?
Andres Riofrio

6
@AndresRiofrio Tôi không thể tìm thấy bất kỳ tài liệu nào từ Mozilla hoặc Microsoft hoặc W3C quy định bất kỳ loại hết hạn bắt buộc nào. Vì vậy, tôi nghĩ rằng câu trả lời là có, tác nhân người dùng có nghĩa vụ phải lưu trữ nội dung được lưu trữ mãi mãi hoặc cho đến khi người dùng yêu cầu rõ ràng rằng nó sẽ bị xóa (hoặc tôi đoán cho đến khi ứng dụng của bạn xóa nội dung của chính nó).
Mũi nhọn

3
Điều này cũng có nghĩa là trình duyệt của bạn tiếp tục phát triển. Bạn sử dụng một ứng dụng một lần, nó lưu trữ nội dung của nó trong trình duyệt của bạn và ứng dụng đó sẽ tồn tại mãi mãi ....
Pieter van Kampen

1
Lượng dữ liệu localStorage bạn có thể lưu trữ trên mỗi trang web là khoảng 10mb, nhưng một trang web trung bình sẽ không lưu trữ nhiều hơn một vài chuỗi, vì vậy tôi không bận tâm về dung lượng lưu trữ
Juan

1
Firefox có một chính sách trục xuất tài liệu ở đây .
ShreevatsaR

268

Tôi sẽ đề nghị lưu dấu thời gian trong đối tượng bạn lưu trữ trong localStorage

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

Bạn có thể phân tích đối tượng, lấy dấu thời gian và so sánh với Ngày hiện tại và nếu cần, hãy cập nhật giá trị của đối tượng.

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

compareTime(dateString, now); //to implement

3
Chà, ngay cả khi thời gian của khách hàng không nhất quán, bạn vẫn có thể tìm cách sử dụng thời gian máy chủ của mình. Giống như lặp lại dấu thời gian thành một div.
Cá heo tối cao

Bạn sẽ phân tích và so sánh dấu thời gian trong một khoảng thời gian (ví dụ: settimoutcứ sau 5 giây) hoặc cho mỗi yêu cầu mà khách hàng gửi đến máy chủ?
ibubi

cách tốt hơn là so sánh ngày cho mỗi yêu cầu người dùng
Terai

36

Bạn có thể sử dụng lscache . Nó tự động xử lý việc này cho bạn, bao gồm cả các trường hợp kích thước lưu trữ vượt quá giới hạn. Nếu điều đó xảy ra, nó bắt đầu cắt tỉa các mục gần nhất với hết hạn được chỉ định.

Từ readme:

lscache.set

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

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

Đây là sự khác biệt thực sự duy nhất giữa các phương pháp lưu trữ thông thường. Nhận, loại bỏ, vv làm việc như nhau.

Nếu bạn không cần nhiều chức năng đó, bạn chỉ cần lưu trữ dấu thời gian với giá trị (thông qua JSON) và kiểm tra xem nó có hết hạn không.

Đáng chú ý, có một lý do chính đáng tại sao bộ nhớ cục bộ lại phụ thuộc vào người dùng. Nhưng, những thứ như lscache sẽ có ích khi bạn cần lưu trữ dữ liệu cực kỳ tạm thời.


Cảm ơn bạn! Điều này thật tuyệt vời cho những gì tôi cần - dữ liệu chỉ cần có trong trường hợp người dùng tạo booboo hoặc trình duyệt bị đóng trước khi họ lưu công việc của họ, nhưng có quá nhiều dữ liệu cho cookie. Tôi đang sử dụng nó cùng với pieroxy.net/blog/pages/lz-opes/index.html .
Peter Smartt

34

Brynner Ferreira, đã mang đến một điểm tốt: lưu trữ khóa anh chị em nơi thông tin hết hạn cư trú. Theo cách này, nếu bạn có số lượng khóa lớn hoặc nếu giá trị của bạn là các đối tượng Json lớn , bạn không cần phân tích chúng để truy cập dấu thời gian.

ở đây có phiên bản cải tiến:

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

Trong setStorage (), elsedòng này có nên expires = Math.abs(1000*expires); //make sure it's positivekhông?
alissonmuller

Chỉ là một điểm cho getStoragecuộc gọi. Nếu bạn cố truy cập trực tiếp vào _expiresInphiên bản của khóa, thì khóa đó sẽ trở thành ..._expiresIn_expiresInkhóa học không tồn tại để nó xóa ..._expiresInkhóa gốc , sau đó khi bạn truy cập vào khóa gốc, lần sau ..._expiresInsẽ không tồn tại và nó sẽ xóa bản gốc Chìa khóa. Tôi sẽ đề nghị bẫy cho điều đó khi tôi bắt gặp điều này trong một trong các dự án của tôi. if(key.indexOf('_expiresIn') > -1) { return localStorage.getItem(key); }
akousmata

24

Mặc dù bộ nhớ cục bộ không cung cấp cơ chế hết hạn, nhưng cookie thì có. Chỉ cần ghép một khóa lưu trữ cục bộ với cookie cung cấp một cách dễ dàng để đảm bảo rằng bộ nhớ cục bộ có thể được cập nhật với các tham số hết hạn giống như cookie.

Ví dụ trong 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

Ví dụ này đặt cookie với tham số mặc định hết hạn khi đóng trình duyệt. Do đó, khi trình duyệt được đóng và mở lại, kho lưu trữ dữ liệu cục bộ cho your_data sẽ được làm mới bằng một cuộc gọi phía máy chủ.

Lưu ý rằng điều này không hoàn toàn giống như loại bỏ lưu trữ dữ liệu cục bộ, thay vào đó, nó đang cập nhật kho lưu trữ dữ liệu cục bộ bất cứ khi nào cookie hết hạn. Tuy nhiên, nếu mục tiêu chính của bạn là có thể lưu trữ nhiều hơn phía máy khách 4K (giới hạn về kích thước cookie), việc ghép cookie và lưu trữ cục bộ này sẽ giúp bạn thực hiện kích thước lưu trữ lớn hơn bằng cách sử dụng cùng một tham số hết hạn như cookie .


Cookies có thể bị xóa, và, tệ hơn nữa, có thể được tắt hoàn toàn.
Cá heo tối cao

1
Tôi thích giải pháp này tốt nhất vì nó cho phép trình duyệt xử lý hết hạn giải pháp lưu trữ của chúng tôi mà không phải sử dụng các thư viện khác hoặc quản lý ngày lưu trữ cục bộ theo cách thủ công.
ecc

10
Hãy nhớ rằng Cookies được gửi trong MỌI yêu cầu.
Lucas Freitas

24

Ở đây rất khuyến khích sử dụng sessionStorage

  • nó giống như localStorage nhưng hủy khi phiên bị hủy / đóng trình duyệt
  • còn localStorage có thể chia sẻ giữa các tab trong khi sessionStorage chỉ có thể sử dụng trong tab hiện tại, nhưng giá trị không thay đổi trên trang làm mới hoặc thay đổi trang
  • sessionStorage cũng hữu ích để giảm lưu lượng mạng đối với cookie

để sử dụng giá trị cài đặt

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

để có được giá trị sử dụng

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

bấm vào đây để xem api

tất cả các cách để thiết lập là

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

tất cả các cách để có được là

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

8
Lưu ý rằng sessionStoragekhông hoạt động để chia sẻ dữ liệu giữa các tab
Bhargava Mummadireddy

14

Vòng đời được điều khiển bởi ứng dụng / người dùng.

Từ tiêu chuẩn :

Tác nhân người dùng chỉ nên hết hạn dữ liệu từ các vùng lưu trữ cục bộ vì lý do bảo mật hoặc khi người dùng yêu cầu làm như vậy. Tác nhân người dùng phải luôn luôn tránh xóa dữ liệu trong khi tập lệnh có thể truy cập dữ liệu đó đang chạy.


10

Từ dự thảo W3C:

Tác nhân người dùng chỉ nên hết hạn dữ liệu từ các vùng lưu trữ cục bộ vì lý do bảo mật hoặc khi người dùng yêu cầu làm như vậy. Tác nhân người dùng phải luôn luôn tránh xóa dữ liệu trong khi tập lệnh có thể truy cập dữ liệu đó đang chạy.

Bạn sẽ muốn thực hiện cập nhật về lịch trình của mình bằng setItem (khóa, giá trị); sẽ thêm hoặc cập nhật khóa đã cho với dữ liệu mới.


Hmm ... có lẽ liệt kê một ngày là một phần của dữ liệu sẽ là một ý tưởng tốt? Hoặc có thể sử dụng một khóa khác nhau mỗi khi dữ liệu thay đổi.
DisgruntledGoat

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

}

4
Tôi thích cách tiếp cận này, vì nó không yêu cầu phân tích dữ liệu trước.
Barshe

3

Nếu ai đó sử dụng Plugin jStorage của jQuery, nó có thể được thêm hạn sử dụng với hàm setTTL nếu plugin jStorage

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

3

Nếu bất cứ ai vẫn đang tìm kiếm một giải pháp nhanh chóng và không muốn phụ thuộc như jquery, v.v. Tôi đã viết một lib nhỏ thêm hết hạn vào lưu trữ cục bộ / phiên / tùy chỉnh, bạn có thể tìm thấy nó với nguồn ở đây:

https://github.com/RonenNess/ExpiredStorage


3

Bạn có thể thử cái này

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

1

Giải pháp sử dụng góc và địa phương:

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

})

Tôi đã kiểm tra trang web và tôi không thấy bất kỳ khóa 'expireTimeInMilliseconds' nào trong API của họ. Đây có phải là một thiết lập không có giấy tờ / không được hỗ trợ?
aaaaaa

1
@PhilOlson đó là một triển khai tùy chỉnh mà tôi đã sử dụng localforage. expireTimeInMillisecondskhông phải là một số localforagethuộc tính, mà là một biến tôi đã sử dụng để kiểm tra xem dữ liệu được lưu trữ có cần hết hạn hay không. Kiểm tra getđịnh nghĩa hàm trên ví dụ của tôi.
Tomas Romero

wow localforagekhông phải là lớp người trợ giúp nhỏ nhẹ mà tôi mong đợi
Simon_Weaver

1

Theo tôi, cách tiếp cận của @ sebarmeli là tốt nhất theo quan điểm của tôi, nhưng nếu bạn chỉ muốn dữ liệu tồn tại trong suốt phiên thì sessionStoragecó lẽ là một lựa chọn tốt hơn:

Đây là một đối tượng toàn cầu (sessionStorage) duy trì một vùng lưu trữ có sẵn trong suốt thời gian của phiên trang. Một phiên trang kéo dài miễn là trình duyệt được mở và tồn tại qua các lần tải lại và khôi phục trang. Mở một trang trong một tab hoặc cửa sổ mới sẽ khiến một phiên mới được bắt đầu.

MDN: sessionStorage


1

Vì lợi ích của người tìm kiếm:

Giống như Fernando, tôi không muốn thêm tải json khi các giá trị được lưu trữ đơn giản. Tôi chỉ cần theo dõi một số tương tác UI và giữ dữ liệu liên quan (ví dụ: cách người dùng sử dụng trang web thương mại điện tử trước khi kiểm tra).

Điều này sẽ không đáp ứng tiêu chí của mọi người, nhưng hy vọng sẽ là một bản sao nhanh + dán khởi động cho ai đó và lưu thêm một lib khác.

LƯU Ý: Điều này sẽ không tốt nếu bạn cần truy xuất các mục riêng lẻ.

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

0

Nếu bạn quen thuộc với đối tượng locaStorage của trình duyệt , bạn biết rằng không có điều khoản nào để cung cấp thời gian hết hạn. Tuy nhiên, chúng ta có thể sử dụng Javascript để thêm một TTL (Thời gian tồn tại) để vô hiệu hóa các mục trong locaStorage sau một khoảng thời gian nhất định.

function setLocalStorage(key, value, ttl) {
    // `item` is an object which contains the original value
    // as well as the time when it's supposed to expire
    const item = {
        value: value,
        expiry: ttl <= 0 ? -1 : new Date().getTime() + ttl
    };
    localStorage.setItem(key, JSON.stringify(item));
}

function getLocalStorage(key) {
    const itemStr = localStorage.getItem(key);
    // if the item doesn't exist, return null
    if (!itemStr) {
        return null;
    }
    const item = JSON.parse(itemStr);
    // compare the expiry time of the item with the current time
    if (item.expiry > 0 && new Date().getTime() > item.expiry) {
        // If the item is expired, delete the item from storage
        // and return null
        localStorage.removeItem(key);
        return null;
    }
    return item.value;
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.