Giải pháp dự phòng cho Bộ nhớ cục bộ HTML5 [đã đóng]


119

Tôi đang tìm kiếm các thư viện và mã javascript có thể mô phỏng localStoragetrên các trình duyệt không có hỗ trợ gốc.

Về cơ bản, tôi muốn viết mã trang web của mình bằng cách sử dụng localStorageđể lưu trữ dữ liệu và biết rằng nó sẽ vẫn hoạt động trên các trình duyệt vốn không hỗ trợ nó. Điều này có nghĩa là một thư viện sẽ phát hiện nếu window.localStoragetồn tại và sử dụng nó nếu có. Nếu nó không tồn tại, thì nó sẽ tạo ra một số loại phương thức lưu trữ cục bộ dự phòng, bằng cách tạo triển khai riêng của nó trong window.localStoragekhông gian tên.

Cho đến nay, tôi đã tìm thấy các giải pháp sau:

  1. Triển khai sessionStorage đơn giản .
  2. Một triển khai sử dụng cookie (không thích thú với ý tưởng này).
  3. Dojo của Dojo.storage , nhưng nó là thứ của riêng mình, không thực sự là một dự phòng.

Tôi hiểu rằng Flash và Silverlight cũng có thể được sử dụng để lưu trữ cục bộ, nhưng chưa tìm thấy gì về việc sử dụng chúng làm dự phòng cho HTML5 localStorage tiêu chuẩn. Có lẽ Google Gears cũng có khả năng này?

Vui lòng chia sẻ bất kỳ thư viện, tài nguyên hoặc đoạn mã liên quan nào mà bạn đã tìm thấy! Tôi đặc biệt quan tâm đến các giải pháp dựa trên javascript hoặc jquery thuần túy, nhưng tôi đoán điều đó khó xảy ra.


sessionStorage và localStorage đều là một phần của thông số kỹ thuật Web Storage ( dev.w3.org/html5/webstorage ). Chỉ có sự khác biệt là trình duyệt sẽ giữ dữ liệu trong bao lâu. Tôi đoán bạn sẽ không tìm thấy một thực hiện, nơi bạn có một nhưng không phải là khác (nhưng tôi không chắc chắn 100%)
rlovtang

1
Điều đáng nói là Gears đã chính thức bị tước quyền vào tháng 2 năm ngoái - tôi sẽ không xây dựng bất cứ thứ gì trên đó.
josh3736

@rlovtang: cảm ơn, tôi biết sự khác biệt giữa phiên và lưu trữ cục bộ. Theo bài báo trên 24ways.org (liên kết đầu tiên được đề cập, giải pháp số 1), Chrome chỉ hỗ trợ localStorage chứ không hỗ trợ sessionStorage. Có lẽ điều đó không còn như vậy nữa, vì bài báo đó đã được viết cách đây ít lâu.
Tauren

@ josh3736: vâng, cá nhân tôi muốn tránh sử dụng cookie và bánh răng. Tôi chắc chắn sẽ không xây dựng bất cứ thứ gì dựa vào nó, nhưng nếu nó là một cơ chế lưu trữ dự phòng cho ai đó đã cài đặt nó và tôi không viết mã trực tiếp vào nó, nó có thể được sử dụng.
Tauren

vì vậy tôi thực sự đã nhầm :) Không biết Chrome đã từng hỗ trợ localStorage nhưng không hỗ trợ sessionStorage. Chrome hiện ít nhất đã hỗ trợ cho cả hai.
rlovtang

Câu trả lời:


56

Tôi sử dụng PersistJS ( kho lưu trữ github ), xử lý lưu trữ phía máy khách một cách liền mạch và minh bạch cho mã của bạn. Bạn sử dụng một API duy nhất và nhận hỗ trợ cho các phụ trợ sau:

  • flash: Flash 8 lưu trữ liên tục.
  • gears: Bộ nhớ liên tục dựa trên Google Gears.
  • localstorage: bộ nhớ nháp HTML5.
  • whatwg_db: Lưu trữ cơ sở dữ liệu nháp HTML5.
  • globalstorage: Bộ nhớ nháp HTML5 (thông số cũ).
  • tức là: Hành vi dữ liệu người dùng của Internet Explorer.
  • cookie: Lưu trữ liên tục dựa trên cookie.

Bất kỳ cái nào trong số đó đều có thể bị vô hiệu hóa — ví dụ: nếu bạn không muốn sử dụng cookie. Với thư viện này, bạn sẽ nhận được hỗ trợ lưu trữ phía máy khách gốc trong IE 5.5+, Firefox 2.0+, Safari 3.1+ và Chrome; và hỗ trợ do plugin hỗ trợ nếu trình duyệt có Flash hoặc Gears. Nếu bạn bật cookie, nó sẽ hoạt động trong mọi thứ (nhưng sẽ bị giới hạn ở 4 kB).


10
PersistJS vẫn được hỗ trợ chứ? Tôi đang tự hỏi làm thế nào nó giải quyết vấn đề trong đó trình duyệt được nâng cấp và phương thức lưu trữ đã chọn thay đổi (giả sử lưu trữ cục bộ khả dụng). Vị trí cũ có trở nên dễ tiếp cận không?
jcalfee314

2
Ít nhất thì nó không giống như đang trong quá trình phát triển tích cực nữa.
Mahn

Đây là một thư viện rất táo bạo. Nếu không có bất kỳ kiến ​​thức nào về kích thước tối đa trong hầu hết các công nghệ, chúng ta nên thống kê rằng ứng dụng của chúng ta chạy với nhiều may mắn ... Ngoài ra, đây dường như chỉ là một giải pháp nếu bạn muốn tiết kiệm <64KB.
dude

@julmot Đó là những gì một thư viện dành cho. Cung cấp sự tiện lợi trong khi loại bỏ những thứ tẻ nhạt. Với đủ thời gian và nghiên cứu, bạn thường có thể tìm ra cách làm cho nó hoạt động, bất kể kích thước tối đa. Tất nhiên, có vẻ như tác giả của dự án mà quyết định đó là quá nhiều ...
William

Bạn có biết điều này có hoạt động với chế độ Duyệt web riêng tư trong Safari không? Hiện tại, tôi đang gặp sự cố trong đó localStorage không được hỗ trợ trong Safari Private Browsing cả macOS và iOS.
Austin

61

Polyfill localStorage đơn giản dựa trên JS thuần túy:

Demo: 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);
        }
    }
}​

4
Tại sao điều này không được công nhận !? Cảm ơn anh bạn!
Robert

4
:) - Tôi không thích thêm toàn bộ lib cho mọi thứ tôi cần.
Aamir Afridi

2
nó có được phép trong JavaScript để xác định var expirescục bộ và sau đó là người dùng trong phạm vi khác không? trong chức năngset
happy_marmoset

3
Chỉ muốn chỉ ra rằng trong khi bạn cho phép đặt thời hạn trên cookie, localStorage sẽ không bao giờ hết hạn. Điều này có thể gây ra một số vấn đề nếu bạn đang tìm kiếm thứ gì đó hết hạn. Có thể có lợi nếu thêm ngày hết hạn vào localstorage và sau đó thực hiện so sánh ngày để xem liệu nó có còn áp dụng hay không. Tất nhiên tôi cũng sẽ tranh luận rằng bạn chỉ nên sử dụng cookie nếu bạn cần hết hạn. Nhưng tôi nghĩ tập lệnh này không nên cho phép hết hạn hoặc cho phép nó, cho cả hai, thay vì không nhất quán như hiện tại.
Hanna

1
@MohsinSaeed ở chế độ riêng tư, tôi nghĩ trình duyệt cũng sẽ không cho phép bạn tạo cookie. superuser.com/questions/589248/…
Aamir Afridi

19

bạn đã xem trang polyfill trên wiki Modernizr chưa?

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

tìm phần lưu trữ web trên trang đó và bạn sẽ thấy 10 giải pháp tiềm năng (tính đến tháng 7 năm 2011).

chúc may mắn! dấu


1
Có vẻ như không ai trong số họ đang làm việc ở chế độ Riêng tư / Ẩn danh (ví dụ: Safari hoặc Chrome), vì cách giải quyết của họ là tạo cookie, chế độ này cũng bị tắt ở chế độ đó.
Alex Klaus

14

Dưới đây là phiên bản phản hồi của Aamir Afridi được sắp xếp gọn gàng, giữ tất cả mã của nó được gói gọn trong phạm vi cục bộ.

Tôi đã xóa các tham chiếu tạo retbiến toàn cục và cũng xóa phân tích cú pháp của các chuỗi "true" và "false" được lưu trữ thành các giá trị boolean trong BrowserStorage.get()phương thức, điều này có thể gây ra sự cố nếu một người đang cố gắng lưu trữ các chuỗi "true" hoặc "sai".

Vì API lưu trữ cục bộ chỉ hỗ trợ các giá trị chuỗi, nên người ta vẫn có thể lưu trữ / truy xuất dữ liệu biến JavaScript cùng với các kiểu dữ liệu thích hợp của chúng bằng cách mã hóa dữ liệu đã nói thành một chuỗi JSON, sau đó có thể được giải mã bằng thư viện mã hóa / giải mã JSON như 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);
        }
    };
})();

10

Cá nhân tôi thích khuếch đại.js hơn . Nó đã hoạt động thực sự tốt đối với tôi trong quá khứ và tôi đã đề xuất nó cho tất cả các nhu cầu lưu trữ cục bộ.

hỗ trợ IE 5+, Firefox 2+, Safari 4+, Chrome, Opera 10.5+, iPhone 2+, Android 2+ và cung cấp một API nhất quán để xử lý bộ nhớ trên nhiều trình duyệt


3

store.js sử dụng userData và IE và localStorage trên các trình duyệt khác.

  • Nó không cố gắng làm bất cứ điều gì quá phức tạp

  • Không cần cookie, không cần flash, không cần jQuery.

  • API sạch.

  • 5 kb nén

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



1

Ghế cắt cỏ dường như cũng là một sự thay thế tốt

một chiếc xe cỏ giống như một chiếc ghế dài ngoại trừ nhỏ hơn và bên ngoài. hoàn hảo cho các ứng dụng di động html5 cần một giải pháp bền bỉ nhẹ, thích ứng, đơn giản và thanh lịch.

  • các bộ sưu tập. một ví dụ xe cỏ thực sự chỉ là một mảng các đối tượng.
  • tính bền bỉ thích nghi. cửa hàng cơ bản được tóm tắt đằng sau một giao diện nhất quán.
  • hành vi thu thập có thể cắm được. đôi khi chúng ta cần người trợ giúp thu thập nhưng không phải lúc nào cũng vậy.

0

lưu trữ thực , sử dụng Gears làm dự phòng.


Cảm ơn. Thật không may, có vẻ như nó sẽ hỗ trợ ít trình duyệt hơn so với đề xuất của @ josh3736 về PersistJS. Tôi vẫn sẽ xem xét nó và đánh giá cao đề xuất.
Tauren
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.