HTML5 本地存储后备解决方案 [关闭]

Posted

技术标签:

【中文标题】HTML5 本地存储后备解决方案 [关闭]【英文标题】:HTML5 Local Storage fallback solutions [closed] 【发布时间】:2011-06-09 04:47:37 【问题描述】:

我正在寻找可以在没有本机支持的浏览器上模拟 localStoragejavascript 库和代码。

基本上,我想使用localStorage 对我的网站进行编码来存储数据,并且知道它仍然可以在本身不支持它的浏览器上运行。这意味着库将检测window.localStorage 是否存在并在存在时使用它。如果它不存在,那么它将通过在window.localStorage 命名空间中创建自己的实现来创建某种本地存储的后备方法。

到目前为止,我已经找到了以下解决方案:

    简单的sessionStorage 实现。 一个实现that uses cookies(对这个想法不感兴趣)。 Dojo 的 dojox.storage,但它是它自己的东西,而不是真正的后备。

我知道 Flash 和 Silverlight 也可用于本地存储,但没有发现任何关于将它们用作标准 html5 localStorage 的备用方案。也许 Google Gears 也有这个功能?

请分享您找到的任何相关库、资源或代码 sn-ps!我对纯 javascript 或基于 jquery 的解决方案特别感兴趣,但我猜这不太可能。

【问题讨论】:

sessionStorage 和 localStorage 都是 Web 存储规范 (dev.w3.org/html5/webstorage) 的一部分。唯一的区别是浏览器将保留数据的时间。我猜你不会找到一个有一个但没有另一个的实现(但我不是 100% 确定) 值得一提的是,Gears 是 officially depriciated last February——我不会在上面构建任何东西。 @rlovtang:谢谢,我知道会话和本地存储之间的区别。根据 24ways.org 文章(有问题的第一个链接,解决方案 #1),Chrome 仅支持 localStorage 而不是 sessionStorage。也许情况不再如此,因为那篇文章是不久前写的。 @josh3736:是的,我个人希望避免使用 cookie 和齿轮。我当然不会构建任何依赖它的东西,但如果它是安装它的人的后备存储机制,并且我没有直接对其进行编码,它可以使用。 所以我实际上错了 :) 不知道 Chrome 曾经支持 localStorage 但不支持 sessionStorage。 Chrome 现在至少支持两者。 【参考方案1】:

基于纯 JS 的简单 localStorage polyfill:

演示:http://jsfiddle.net/aamir/S4X35/

HTML:

<a href='#' onclick="store.set('foo','bar')">set key: foo, with value: bar</a><br/>
<a href='#' onclick="alert(store.get('foo'))">get key: foo</a><br/>
<a href='#' onclick="store.del('foo')">delete key: foo</a>​

JS:

window.store = 
    localStoreSupport: function() 
        try 
            return 'localStorage' in window && window['localStorage'] !== null;
         catch (e) 
            return false;
        
    ,
    set: function(name,value,days) 
        if (days) 
            var date = new Date();
            date.setTime(date.getTime()+(days*24*60*60*1000));
            var expires = "; expires="+date.toGMTString();
        
        else 
            var expires = "";
        
        if( this.localStoreSupport() ) 
            localStorage.setItem(name, value);
        
        else 
            document.cookie = name+"="+value+expires+"; path=/";
        
    ,
    get: function(name) 
        if( this.localStoreSupport() ) 
            var ret = localStorage.getItem(name);
            //console.log(typeof ret);
            switch (ret) 
              case 'true': 
                  return true;
              case 'false':
                  return false;
              default:
                  return ret;
            
        
        else 
            // cookie fallback
            /*
             * after adding a cookie like
             * >> document.cookie = "bar=test; expires=Thu, 14 Jun 2018 13:05:38 GMT; path=/"
             * the value of document.cookie may look like
             * >> "foo=value; bar=test"
             */
            var nameEQ = name + "=";  // what we are looking for
            var ca = document.cookie.split(';');  // split into separate cookies
            for(var i=0;i < ca.length;i++) 
                var c = ca[i];  // the current cookie
                while (c.charAt(0)==' ') c = c.substring(1,c.length);  // remove leading spaces
                if (c.indexOf(nameEQ) == 0)   // if it is the searched cookie
                    var ret = c.substring(nameEQ.length,c.length);
                    // making "true" and "false" a boolean again.
                    switch (ret) 
                      case 'true':
                          return true;
                      case 'false':
                          return false;
                      default:
                          return ret;
                    
                
            
            return null; // no cookie found
        
    ,
    del: function(name) 
        if( this.localStoreSupport() ) 
            localStorage.removeItem(name);
        
        else 
            this.set(name,"",-1);
        
    
​

【讨论】:

为什么没有得到认可!?谢谢大佬! :) - 我不喜欢为我需要的一切添加整个库。 JavaScript 中是否允许在本地定义var expires,然后在其他范围内定义用户?在函数set 只是想指出,当您允许在 cookie 上设置过期时间时,localStorage 永远不会过期。如果您正在寻找过期的东西,这可能会导致一些问题。在本地存储中添加过期日期然后进行日期比较以查看它是否仍然适用可能是有益的。当然,我也会争辩说,如果你需要过期,你应该只使用 cookie。但我认为这个脚本不应该允许过期或允许过期,而不是像现在这样不一致。 @MohsinSaeed 在私人模式下,我认为浏览器也不允许您创建 cookie。 superuser.com/questions/589248/…【参考方案2】:

我使用PersistJS (github repository),它对您的代码无缝且透明地处理客户端存储。您使用单个 API 并获得对以下后端的支持:

flash:Flash 8 持久存储。 gears:基于 Google Gears 的持久存储。 localstorage:HTML5 草稿存储。 whatwg_db:HTML5 草案数据库存储。 globalstorage:HTML5 草稿存储(旧规范)。 即:Internet Explorer 用户数据行为。 cookie:基于 Cookie 的持久存储。

其中任何一个都可以禁用 - 例如,如果您不想使用 cookie。使用这个库,您将在 IE 5.5+、Firefox 2.0+、Safari 3.1+ 和 Chrome 中获得本机客户端存储支持;如果浏览器有 Flash 或 Gears,则提供插件辅助支持。如果您启用 cookie,它将适用于所有内容(但将限制为 4 kB)。

【讨论】:

仍然支持 PersistJS 吗?我想知道它如何解决浏览器升级和选择的存储方法发生变化的问题(比如本地存储可用)。旧位置是否无法访问? 它至少看起来不像在积极开发中了。 这是一个非常大胆的图书馆。如果不了解大多数技术中的最大大小,我们应该知道我们的应用程序运行得非常好......此外,如果您想节省 @julmot 这就是图书馆的用途。提供便利,同时抽象出繁琐的东西。通过足够的研究和时间,您通常可以弄清楚如何使其工作,而不管最大尺寸如何。当然,看起来那个项目的作者认为它太多了...... 你知道这是否适用于 Safari 隐私浏览模式吗?目前我遇到的问题是 macOS 和 ios 的 Safari 隐私浏览不支持 localStorage。【参考方案3】:

你看过 Modernizr wiki 上的 polyfill 页面吗?

https://github.com/Modernizr/Modernizr/wiki/HTML5-Cross-browser-Polyfills

在该页面上查找 webstorage 部分,您将看到 10 个潜在的解决方案(截至 2011 年 7 月)。

祝你好运! 标记

【讨论】:

似乎他们都没有在私人/隐身模式下工作(例如 Safari 或 Chrome),因为他们的解决方法是创建 cookie,在该模式下也被禁用。【参考方案4】:

下面是 Aamir Afridi 响应的整理版本,它将所有代码封装在本地范围内。

我删除了创建全局 ret 变量的引用,还删除了将存储的“true”和“false”字符串解析为 BrowserStorage.get() 方法中的布尔值,如果有人试图这样做,这可能会导致问题实际上存储字符串“true”或“false”。

由于本地存储 API 仅支持字符串值,因此仍然可以通过将 JavaScript 变量数据及其适当的数据类型编码为 JSON 字符串来存储/检索这些数据,然后可以使用 JSON 编码/解码库等进行解码如https://github.com/douglascrockford/JSON-js

var BrowserStorage = (function() 
    /**
     * Whether the current browser supports local storage as a way of storing data
     * @var Boolean
     */
    var _hasLocalStorageSupport = (function() 
        try 
            return 'localStorage' in window && window['localStorage'] !== null;
         catch (e) 
            return false;
        
    )();

    /**
     * @param String name The name of the property to read from this document's cookies
     * @return ?String The specified cookie property's value (or null if it has not been set)
     */
    var _readCookie = function(name) 
        var nameEQ = name + "=";
        var ca = document.cookie.split(';');
        for (var i = 0; i < ca.length; i++) 
            var c = ca[i];
            while (c.charAt(0) == ' ') c = c.substring(1, c.length);
            if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
        

        return null;
    ;

    /**
     * @param String name The name of the property to set by writing to a cookie
     * @param String value The value to use when setting the specified property
     * @param int [days] The number of days until the storage of this item expires
     */
    var _writeCookie = function(name, value, days) 
        var expiration = (function() 
            if (days) 
                var date = new Date();
                date.setTime(date.getTime() + (days*24*60*60*1000));
                return "; expires=" + date.toGMTString();
            
            else 
                return "";
            
        )();

        document.cookie = name + "=" + value + expiration + "; path=/";
    ;

    return 
        /**
         * @param String name The name of the property to set
         * @param String value The value to use when setting the specified property
         * @param int [days] The number of days until the storage of this item expires (if storage of the provided item must fallback to using cookies)
         */
        set: function(name, value, days) 
            _hasLocalStorageSupport
                ? localStorage.setItem(name, value)
                : _writeCookie(name, value, days);
        ,

        /**
         * @param String name The name of the value to retrieve
         * @return ?String The value of the 
         */
        get: function(name) 
            return _hasLocalStorageSupport
                ? localStorage.getItem(name) 
                : _readCookie(name);
        ,

        /**
         * @param String name The name of the value to delete/remove from storage
         */
        remove: function(name) 
            _hasLocalStorageSupport
                ? localStorage.removeItem(name)
                : this.set(name, "", -1);
        
    ;
)();

【讨论】:

【参考方案5】:

我个人更喜欢amplify.js。过去它对我来说非常有效,我推荐它来满足所有本地存储需求。

支持 IE 5+、Firefox 2+、Safari 4+、Chrome、Opera 10.5+、iPhone 2+、android 2+,并提供一致的 API 来处理跨浏览器的存储

【讨论】:

【参考方案6】:

store.js 在其他浏览器上使用 userData 和 IE 和 localStorage。

它不会尝试做任何过于复杂的事情

无需 cookie、无需 Flash、无需 jQuery。

清洁 API。

5 kb 压缩

https://github.com/marcuswestin/store.js

【讨论】:

【参考方案7】:

MDN page for DOM storage 提供了几种使用 cookie 的解决方法。

【讨论】:

【参考方案8】:

Lawnchair 似乎也是一个不错的选择

草坪椅有点像沙发,除了更小和外面。完美的 适用于需要轻量级、自适应、简单和 优雅的持久性解决方案。

集合。草坪椅实例实际上只是一个对象数组。 自适应持久性。底层存储被抽象在一个一致的接口后面。 可插入的收集行为。有时我们需要收集助手,但并非总是如此。

【讨论】:

【参考方案9】:

有realstorage,它使用 Gears 作为后备。

【讨论】:

谢谢。不幸的是,它支持的浏览器似乎比@josh3736 建议的 PersistJS 少。我还是会看看它,并感谢您的建议。

以上是关于HTML5 本地存储后备解决方案 [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

html5 下载属性的任何后备客户端解决方案?

播放带有 HTML5 后备的 FLV 视频

HTML5 视频后备 - 无法在本地 Flash 播放器中播放视频文件

iCloud Core Data iOS 6 到 iOS 7 最初是空的本地后备存储

使用 mediaelement.js 与 HTML5 后备的 Flash 视频

如果没有值,HTML5 本地存储对象会返回啥? [关闭]