localStorage設置過期時間


場景

瀏覽器端需要存儲一個用戶的標識和cookie一樣需要過期時間,但是用的是localStorage存儲。而localStorage一經存儲除非手動刪除是不會過期的。那就需要自己實現過期機制。網上找了幾種簡單的方法。

方案一:ES5擴展Storage

思路很簡單,存儲的值加一個時間戳,下次取值時驗證時間戳。
注意: localStorage只能存儲字符,存入時將對象轉為json字符串,讀取時也要解析

Storage.prototype.setExpire = (key, value, expire) => {
	let obj = {
	data: value,
	time: Date.now(),
	expire: expire
	};
	//localStorage 設置的值不能為對象,轉為json字符串
	localStorage.setItem(key, JSON.stringify(obj));
}

Storage.prototype.getExpire = key => {
    let val = localStorage.getItem(key);
    if (!val) {
        return val;
    }
    val = JSON.parse(val);
    if (Date.now() - val.time > val.expire) {
        localStorage.removeItem(key);
        return null;
    }
    return val.data;
}

測試一下:

localStorage.setExpire('userId','zhangsan',5000);
window.setInterval(()=>{
    console.log(localStorage.getExpire("userId"));
},1000)

前5秒還是有值的,之后即為null

image

方案二:ES6擴展Storage

大體思路和方案一是一樣的只不過是用了ES6的最新語法實現。

class Storage {

    constructor(props) {
        this.props = props || {}
        this.source = this.props.source || window.localStorage
        this.initRun();
    }
    initRun(){
        /*
        * set 存儲方法
        * @ param {String}     key 鍵
        * @ param {String}     value 值,存儲的值可能是數組/對象,不能直接存儲,需要轉換 JSON.stringify
        * @ param {String}     expired 過期時間,以分鍾為單位
        */
        const reg = new RegExp("__expires__");
        let data = this.source;
        let list = Object.keys(data);
        if(list.length > 0){
            list.map((key,v)=>{
                if( !reg.test(key )){
                    let now = Date.now();
                    let expires = data[`${key}__expires__`]||Date.now+1;
                    if (now >= expires ) {
                        this.remove(key);
                    };
                };
                return key;
            });
        };
    }

	set(key, value, expired) {
	    /*
	    * set 存儲方法
	    * @ param {String}     key 鍵
	    * @ param {String}     value 值,
	    * @ param {String}     expired 過期時間,以毫秒為單位,非必須
	    */
	    let source = this.source;
	    source[key] = JSON.stringify(value);
	    if (expired){
	        source[`${key}__expires__`] = Date.now() + expired
	    };
	    return value;
	}

    get(key) {
        /*
        * get 獲取方法
        * @ param {String}     key 鍵
        * @ param {String}     expired 存儲時為非必須字段,所以有可能取不到,默認為 Date.now+1
        */
        const source = this.source,
        expired = source[`${key}__expires__`]||Date.now+1;
        const now = Date.now();
    
        if ( now >= expired ) {
            this.remove(key);
            return;
        }
        const value = source[key] ? JSON.parse(source[key]) : source[key];
        return value;
	}

	remove(key) {
	    const data = this.source,
	        value = data[key];
	    delete data[key];
	    delete data[`${key}__expires__`];
	    return value;
	}

}

其中set(),get(),remove()方法可以理解用來存、取、刪, initRun()做什么用呢?過期的值只有取時才能知道是不是過期,不取一直存着。initRun()constructor只是在初始化時實現清理,也不是一定即時。另外寫一個定時器去清理貌似也不值當,所以覺得做到這樣已經夠用了。

使用如下代碼進行測試一下,效果和方案一相同

var ls=new Storage();
ls.set('userId','zhangsan',5000);
window.setInterval(()=>{
    console.log(ls.get("userId"));
},1000)

參考


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM