Rozwiązania rezerwowe HTML5 Local Storage [zamknięte]

119

Szukam bibliotek javascript i kodu, który może symulować localStoragew przeglądarkach, które nie mają natywnej obsługi.

Zasadniczo chciałbym zakodować moją witrynę za pomocą localStoragedo przechowywania danych i wiedzieć, że będzie ona nadal działać w przeglądarkach, które jej natywnie nie obsługują. Oznaczałoby to, że biblioteka wykryłaby, czy window.localStorageistnieje, i użyłaby jej, jeśli tak. Jeśli tak nie jest, stworzyłoby jakąś metodę rezerwową pamięci lokalnej, tworząc własną implementację w window.localStorageprzestrzeni nazw.

Do tej pory znalazłem takie rozwiązania:

  1. Prosta implementacja sessionStorage .
  2. Implementacja korzystająca z plików cookie (niezadowolona z tego pomysłu).
  3. Dojox.storage w Dojo , ale to jest własna rzecz, a nie rozwiązanie awaryjne.

Rozumiem, że Flash i Silverlight mogą być również używane do przechowywania lokalnego, ale nie znalazłem nic na temat używania ich jako rezerwy dla standardowego localStorage HTML5. Być może Google Gears również ma taką możliwość?

Udostępnij wszystkie powiązane biblioteki, zasoby lub fragmenty kodu, które znalazłeś! Byłbym szczególnie zainteresowany rozwiązaniami opartymi na czystym javascript lub jquery, ale zgaduję, że jest to mało prawdopodobne.

Tauren
źródło
sessionStorage i localStorage są częścią specyfikacji Web Storage ( dev.w3.org/html5/webstorage ). Jedyną różnicą jest to, jak długo przeglądarka będzie przechowywać dane. Chyba nie znajdzie implementację gdzie trzeba, ale nie inne (ale nie jestem w 100% pewien)
rlovtang
1
Warto wspomnieć, że Gears został oficjalnie pozbawiony wartości w lutym zeszłego roku - niczego bym na nim nie budował.
josh3736
@rlovtang: dzięki, zdaję sobie sprawę z różnicy między sesją a pamięcią lokalną. Zgodnie z artykułem 24ways.org (pierwszy odsyłacz, rozwiązanie nr 1), Chrome obsługuje tylko magazyn localStorage, a nie sessionStorage. Być może już tak nie jest, ponieważ ten artykuł został napisany jakiś czas temu.
Tauren
@ josh3736: tak, osobiście chciałbym unikać ciasteczek i narzędzi. Z pewnością nie zbudowałbym na nim niczego zależnego, ale gdyby był to awaryjny mechanizm przechowywania dla kogoś, kto go zainstalował, a nie kodowałem bezpośrednio do niego, mógłby zostać użyty.
Tauren
więc naprawdę się myliłem :) Nie wiedziałem, że Chrome kiedyś obsługiwał localStorage, ale nie sessionStorage. Chrome ma teraz wsparcie dla obu.
rlovtang

Odpowiedzi:

56

Używam PersistJS ( repozytorium github ), które bezproblemowo i przejrzyście obsługuje przechowywanie po stronie klienta dla twojego kodu. Używasz jednego interfejsu API i otrzymujesz wsparcie dla następujących backendów:

  • flash: pamięć trwała Flash 8.
  • biegów: trwała pamięć masowa oparta na wtyczce Google Gears.
  • localstorage: przechowywanie wersji roboczych HTML5.
  • whatwg_db: przechowywanie roboczej bazy danych HTML5.
  • globalstorage: przechowywanie wersji roboczych HTML5 (stara specyfikacja).
  • tj .: zachowanie danych użytkownika przeglądarki Internet Explorer.
  • cookie: trwałe przechowywanie oparte na plikach cookie.

Każde z nich można wyłączyć - jeśli na przykład nie chcesz używać plików cookie. Dzięki tej bibliotece otrzymasz natywną obsługę pamięci masowej po stronie klienta w przeglądarkach IE 5.5+, Firefox 2.0+, Safari 3.1+ i Chrome; i wsparcie wspomagane przez wtyczki, jeśli przeglądarka ma Flash lub Gears. Jeśli włączysz obsługę plików cookie, będzie działać we wszystkim (ale będzie ograniczony do 4 kB).

josh3736
źródło
10
Czy PersistJS jest nadal obsługiwany? Zastanawiam się, jak rozwiązuje problem polegający na uaktualnieniu przeglądarki i zmianie wybranej metody przechowywania (powiedzmy, że pamięć lokalna staje się dostępna). Czy stara lokalizacja staje się niedostępna?
jcalfee314
2
Przynajmniej nie wygląda na to, że jest już w aktywnym rozwoju.
Mahn
To bardzo odważna biblioteka. Bez wiedzy na temat maksymalnego rozmiaru w większości technologii powinniśmy być usatysfakcjonowani, że nasza aplikacja działa z dużym szczęściem ... Wydaje się, że jest to tylko rozwiązanie, jeśli chcesz zaoszczędzić <64 KB.
koleś
@julmot Po to jest biblioteka. Zapewnij wygodę, jednocześnie usuwając żmudne rzeczy. Mając wystarczająco dużo badań i czasu, zwykle możesz dowiedzieć się, jak to działa, niezależnie od maksymalnego rozmiaru. Oczywiście wygląda na to, że autor tego projektu uznał, że to za dużo ...
William
Czy wiesz, czy to działa w trybie przeglądania prywatnego w Safari? Obecnie mam problem polegający na tym, że localStorage nie jest obsługiwany w przeglądaniu prywatnym Safari zarówno w systemie MacOS, jak i iOS.
Austin
61

Prosty wypełniacz localStorage oparty na czystym JS:

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);
        }
    }
}​
Aamir Afridi
źródło
4
Dlaczego to nie zyskuje uznania !? Dzięki!
Robert
4
:) - Nie lubię dodawać całej biblioteki do wszystkiego, czego potrzebuję.
Aamir Afridi
2
czy w JavaScript wolno definiować var expireslokalnie, a następnie użytkownika w innym zakresie? in functionset
happy_marmoset
3
Chciałem tylko zaznaczyć, że chociaż pozwalasz na ustawienie wygaśnięcia w pliku cookie, localStorage nigdy nie wygaśnie. Może to spowodować pewne problemy, jeśli chcesz, aby coś wygasło. Korzystne może być dodanie daty wygaśnięcia do lokalnego magazynu, a następnie porównanie dat, aby sprawdzić, czy nadal obowiązuje. Oczywiście argumentowałbym również, że jeśli potrzebujesz wygaśnięcia, powinieneś po prostu użyć pliku cookie. Ale myślę, że ten skrypt nie powinien zezwalać na wygaśnięcie lub zezwalać na to w obu przypadkach, zamiast być niespójny, jak jest obecnie.
Hanna
1
@MohsinSaeed w trybie prywatnym, myślę, że przeglądarka nie pozwoli Ci również na tworzenie plików cookie. superuser.com/questions/589248/…
Aamir Afridi
19

czy widzieliście stronę polyfill na wiki Modernizr?

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

poszukaj sekcji magazynu internetowego na tej stronie, a zobaczysz 10 potencjalnych rozwiązań (stan na lipiec 2011).

powodzenia! znak

Mark Lummus
źródło
1
Wygląda na to, że żaden z nich nie działa w trybie Private / Incognito (np. Safari czy Chrome), ponieważ ich obejściem jest tworzenie plików cookie, które również jest wyłączone w tym trybie.
Alex Klaus,
14

Poniżej znajduje się uporządkowana wersja odpowiedzi Aamira Afridiego, w której cały kod jest zamknięty w lokalnym zakresie.

Usunąłem odniesienia, które tworzą retzmienną globalną , a także usunąłem parsowanie przechowywanych ciągów „prawda” i „fałsz” na wartości logiczne w ramach BrowserStorage.get()metody, co może powodować problemy, jeśli ktoś próbuje w rzeczywistości przechowywać ciągi „prawda” lub "fałszywe".

Ponieważ lokalny interfejs API pamięci obsługuje tylko wartości ciągów, nadal można przechowywać / pobierać dane zmiennych JavaScript wraz z ich odpowiednimi typami danych, kodując te dane w ciąg JSON, który można następnie dekodować za pomocą biblioteki kodowania / dekodowania JSON, takiej jak 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);
        }
    };
})();
Steven
źródło
10

Osobiście wolę amplify.js . W przeszłości działał bardzo dobrze i poleciłem go do wszystkich lokalnych potrzeb przechowywania.

obsługuje IE 5+, Firefox 2+, Safari 4+, Chrome, Opera 10.5+, iPhone 2+, Android 2+ i zapewnia spójny interfejs API do obsługi pamięci masowej w różnych przeglądarkach

raidfive
źródło
3

store.js używa danych userData i IE oraz localStorage w innych przeglądarkach.

  • Nie próbuje robić niczego zbyt skomplikowanego

  • Bez plików cookie, bez pamięci flash, bez jQuery.

  • Czysty interfejs API.

  • Skompresowane 5 kb

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

Mikko Ohtamaa
źródło
1

Krzesło również wydaje się dobrą alternatywą

fotel ogrodowy jest trochę jak kanapa, z wyjątkiem mniejszego i zewnętrznego. idealny dla aplikacji mobilnych html5, które wymagają lekkiego, adaptacyjnego, prostego i eleganckiego rozwiązania trwałego.

  • kolekcje. instancja wózka ogrodowego to tak naprawdę tylko tablica obiektów.
  • trwałość adaptacyjna. bazowy sklep jest wyodrębniony za spójnym interfejsem.
  • zachowanie kolekcji z możliwością podłączania. czasami potrzebujemy pomocników w zbieraniu danych, ale nie zawsze.
j0k
źródło
0

Istnieje realstorage , który używa wtyczki Gears jako rozwiązania zastępczego.

Gaurav
źródło
Dzięki. Niestety wygląda na to, że obsługuje mniej przeglądarek niż sugestia @ josh3736 dotycząca PersistJS. Nadal się temu przyjrzę i docenię sugestię.
Tauren