欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

cookie,sessionStorage与localStorage

程序员文章站 2022-06-10 13:06:15
...

1. cookie

cookie的设计初衷是给服务端脚本用来存储少量数据的 ,该数据会在每次请求一个相关URL时传递到服务器中。cookie就像服务器给用户贴的“嗨,我叫”的贴纸一样,用户访问web站点时,这个web站点就可以读取那个服务器贴在用户身上的所有贴纸。
cookie的有效期和作用域
cookie默认的有效期很短暂,它只能持续在web浏览器的会话期间,一旦用户关闭浏览器,cookie保存的数据就丢失了。cookie的作用域并不是局限在浏览器的单个窗口中,它的有效期和整个浏览器进程而不是单个浏览器窗口的有效期一致。一旦设置了有效期,浏览器就会将cookie数据存储在一个文件中,并且直到过了指定的有效期才会删除该文件。cookie的作用域是通过文档源和文档路径来确定的。该作用域通过cookie的path和domain属性也是可配置的。默认情况下,cookie和创建它的web页面有关,并对该web页面以及该web页面同目录或者子目录的其他web页面可见。

2. sessionStorage

sessionStorage对象存储特定于某个会话的数据,也就是该数据只保存到浏览器关闭。这个对象就想会话cookie,也会在浏览器关闭后消失。存储在sessionStorage中的数据可以跨页面刷新而存在。存储在sessionStorage的数据只能由最初给对象存储数据的页面访问到,所以对多页面应用有限制。

3. localStorage

通过localStorage存储的数据是永久性的,除非web应用刻意删除存储的数据,或者用户通过设置浏览器配置来删除。否则数据将一直保留在用户的电脑上,永不过期。localStorage的作用域是限定在文档源级别的。

4. 简单封装操作api

/**
 * 
 *
 * 从store方法名上区分了sessionStorage 和 localStorage,各自有各自的方法
 *
 * 增加了 has,getAll,each,serialize,deserialize 方法,
 *
 * 基于jquery.cookie 增加了操作cookie的方法 get,set,getAll,remove
 *
 **/

"use strict"
// Module export pattern from
// https://github.com/umdjs/umd/blob/master/returnExports.js
;(function (root, factory) {
    if (typeof define === 'function' && define.amd) {
        // AMD. Register as an anonymous module.
        define([], factory);
    } else if (typeof exports === 'object') {
        // Node. Does not work with strict CommonJS, but
        // only CommonJS-like environments that support module.exports,
        // like Node.
        module.exports = factory();
    } else {
        // Browser globals (root is window)
        root.store = factory();
    }
}(this, function () {

    // Store.js
    var store = {},
        win = (typeof window != 'undefined' ? window : global),
        doc = win.document,
        localStorageName = 'localStorage',
        sessionStorageName = 'sessionStorage',
        scriptTag = 'script',
        storage,_storage;

    store.disabled = false;

    store.setLocal = function(key, value) {};
    store.getLocal = function(key, defaultVal) {};
    store.hasLocal = function(key) { return store.getLocal(key) !== undefined };
    store.removeLocal = function(key) {};
    store.clearLocal = function() {};

    store.getAllLocal = function() {};
    store.eachLocal = function() {};

    store.setSession = function(key, value) {};
    store.getSession = function(key, defaultVal) {};
    store.hasSession = function(key) { return store.getSession(key) !== undefined };
    store.removeSession = function(key) {};
    store.clearSession = function() {};

    store.getAllSession = function() {};
    store.eachSession = function() {};

    store.serialize = function(value) {
        return JSON.stringify(value)
    };
    store.deserialize = function(value) {
        if (typeof value != 'string') { return undefined }
        try { return JSON.parse(value) }
        catch(e) { return value || undefined }
    };

    // 获取cookie
    store.getCookie=function (name) {
        $.cookie.json = true;
        return $.cookie(name);
    };

    // 是否存在cookie
    store.hasCookie=function (name) {
        $.cookie.json = true;

        if ($.cookie(name)){
            return true
        }else{
            return false
        }
    };

    // 设置cookie
    store.setCookie = function (name, value, days, path) {
        $.cookie.json = true;

        if(days !==undefined && path!==undefined){
            $.cookie(name, value,{expires:days,path:path});

        }else if(days !==undefined && path===undefined){
            $.cookie(name, value,{expires:days});

        }else if(days ===undefined && path===undefined){
            $.cookie(name, value);
        }

    };

    // 获取所有cookie键值对
    store.getAllCookie = function () {
        return $.cookie();
    };

    // 删除cookie 必须传入与设置cookie时相同的参数,如 path, domain , secure
    store.removeCookie =function (name,path) {
        var result;
        if(path){
            result = $.removeCookie(name, { path: path });
        }else {
            result = $.removeCookie(name);
        }
        if(!result){console.log('删除cookie'+name+'失败')}
    };

    // Functions to encapsulate questionable FireFox 3.6.13 behavior
    // when about.config::dom.storage.enabled === false
    // See https://github.com/marcuswestin/store.js/issues#issue/13
    function isLocalStorageNameSupported() {
        try { return (localStorageName in win && win[localStorageName]) }
        catch(err) { return false }
    }

    function isSessionStorageNameSupported() {
        try { return (sessionStorageName in win && win[sessionStorageName]) }
        catch(err) { return false }
    }
    // sessionStorage API
    if(isSessionStorageNameSupported()){
        _storage = win[sessionStorageName];
        store.setSession = function(key, val) {
            if (val === undefined) { return store.removeSession(key) }
            _storage.setItem(key, store.serialize(val));
            return val
        };
        store.getSession = function(key, defaultVal) {
            var val = store.deserialize(_storage.getItem(key));
            return (val === undefined ? defaultVal : val)
        };
        store.removeSession = function(key) { _storage.removeItem(key) };
        store.clearSession = function() { _storage.clear() };
        store.getAllSession = function() {
            var ret = {};
            store.eachSession(function(key, val) {
                ret[key] = val
            });
            return ret
        };
        store.eachSession = function(callback) {
            for (var i=0; i<_storage.length; i++) {
                var key = _storage.key(i);
                callback(key, store.getSession(key))
            }
        }
    }
    // localStorage API
    if (isLocalStorageNameSupported()) {
        storage = win[localStorageName];
        store.setLocal = function(key, val) {
            if (val === undefined) { return store.removeLocal(key) }
            storage.setItem(key, store.serialize(val));
            return val
        };
        store.getLocal = function(key, defaultVal) {
            var val = store.deserialize(storage.getItem(key));
            return (val === undefined ? defaultVal : val)
        };
        store.removeLocal = function(key) { storage.removeItem(key) };
        store.clearLocal = function() { storage.clear() };
        store.getAllLocal = function() {
            var ret = {};
            store.eachLocal(function(key, val) {
                ret[key] = val
            });
            return ret
        };
        store.eachLocal = function(callback) {
            for (var i=0; i<storage.length; i++) {
                var key = storage.key(i);
                callback(key, store.getLocal(key))
            }
        }
    } else if (doc && doc.documentElement.addBehavior) {
        var storageOwner,
            storageContainer;
        // Since #userData storage applies only to specific paths, we need to
        // somehow link our data to a specific path.  We choose /favicon.ico
        // as a pretty safe option, since all browsers already make a request to
        // this URL anyway and being a 404 will not hurt us here.  We wrap an
        // iframe pointing to the favicon in an ActiveXObject(htmlfile) object
        // (see: http://msdn.microsoft.com/en-us/library/aa752574(v=VS.85).aspx)
        // since the iframe access rules appear to allow direct access and
        // manipulation of the document element, even for a 404 page.  This
        // document can be used instead of the current document (which would
        // have been limited to the current path) to perform #userData storage.
        try {
            storageContainer = new ActiveXObject('htmlfile');
            storageContainer.open();
            storageContainer.write('<'+scriptTag+'>document.w=window</'+scriptTag+'><iframe src="/favicon.ico"></iframe>');
            storageContainer.close();
            storageOwner = storageContainer.w.frames[0].document;
            storage = storageOwner.createElement('div')
        } catch(e) {
            // somehow ActiveXObject instantiation failed (perhaps some special
            // security settings or otherwse), fall back to per-path storage
            storage = doc.createElement('div');
            storageOwner = doc.body
        }
        var withIEStorage = function(storeFunction) {
            return function() {
                var args = Array.prototype.slice.call(arguments, 0);
                args.unshift(storage);
                // See http://msdn.microsoft.com/en-us/library/ms531081(v=VS.85).aspx
                // and http://msdn.microsoft.com/en-us/library/ms531424(v=VS.85).aspx
                storageOwner.appendChild(storage);
                storage.addBehavior('#default#userData');
                storage.load(localStorageName);
                var result = storeFunction.apply(store, args);
                storageOwner.removeChild(storage);
                return result
            }
        };

        // In IE7, keys cannot start with a digit or contain certain chars.
        // See https://github.com/marcuswestin/store.js/issues/40
        // See https://github.com/marcuswestin/store.js/issues/83
        var forbiddenCharsRegex = new RegExp("[!\"#$%&'()*+,/\\\\:;<=>[email protected][\\]^`{|}~]", "g");
        var ieKeyFix = function(key) {
            return key.replace(/^d/, '___$&').replace(forbiddenCharsRegex, '___')
        };
        store.setLocal = withIEStorage(function(storage, key, val) {
            key = ieKeyFix(key);
            if (val === undefined) { return store.remove(key) }
            storage.setAttribute(key, store.serialize(val));
            storage.save(localStorageName);
            return val
        });
        store.getLocal = withIEStorage(function(storage, key, defaultVal) {
            key = ieKeyFix(key);
            var val = store.deserialize(storage.getAttribute(key));
            return (val === undefined ? defaultVal : val)
        });
        store.removeLocal = withIEStorage(function(storage, key) {
            key = ieKeyFix(key);
            storage.removeAttribute(key);
            storage.save(localStorageName)
        });
        store.clearLocal = withIEStorage(function(storage) {
            var attributes = storage.XMLDocument.documentElement.attributes;
            storage.load(localStorageName);
            for (var i=attributes.length-1; i>=0; i--) {
                storage.removeAttribute(attributes[i].name)
            }
            storage.save(localStorageName)
        });
        store.getAllLocal = function(storage) {
            var ret = {};
            store.eachLocal(function(key, val) {
                ret[key] = val
            });
            return ret
        };
        store.eachLocal = withIEStorage(function(storage, callback) {
            var attributes = storage.XMLDocument.documentElement.attributes;
            for (var i=0, attr; attr=attributes[i]; ++i) {
                callback(attr.name, store.deserialize(storage.getAttribute(attr.name)))
            }
        })
    }

    try {
        var testKey = '__storejs__';
        store.set(testKey, testKey);
        if (store.get(testKey) != testKey) { store.disabled = true }
        store.remove(testKey)
    } catch(e) {
        store.disabled = true
    }
    store.enabled = !store.disabled;

    return store
}));