Резервные решения для локального хранилища HTML5 [закрыто]

119

Я ищу библиотеки и код javascript, которые можно моделировать localStorageв браузерах, не имеющих встроенной поддержки.

По сути, я хотел бы кодировать свой сайт localStorageдля хранения данных и знать, что он по-прежнему будет работать в браузерах, которые его не поддерживают. Это означало бы, что библиотека обнаружит, window.localStorageсуществует ли, и будет использовать ее, если она есть. Если он не существует, он создаст своего рода резервный метод локального хранилища, создав свою собственную реализацию в window.localStorageпространстве имен.

Пока что я нашел эти решения:

  1. Простая реализация sessionStorage .
  2. Реализация , использующая файлы cookie (не в восторге от этой идеи).
  3. Додзё dojox.storage , но это собственное дело, на самом деле не запасной вариант.

Я понимаю, что Flash и Silverlight также можно использовать для локального хранилища, но я не нашел ничего, чтобы использовать их в качестве запасного варианта для стандартного HTML5 localStorage. Возможно, у Google Gears тоже есть такая возможность?

Пожалуйста, поделитесь любыми связанными библиотеками, ресурсами или фрагментами кода, которые вы нашли! Меня бы особенно интересовали решения на основе чистого javascript или jquery, но я предполагаю, что это маловероятно.

Таурен
источник
sessionStorage и localStorage являются частью спецификации веб-хранилища ( dev.w3.org/html5/webstorage ). Единственная разница в том, как долго браузер будет хранить данные. Думаю, вы не найдете реализации, в которой есть одно, но нет другого (но я не уверен на 100%)
rlovtang
1
Стоит отметить, что в феврале прошлого года Gears был официально закрыт - я бы не стал ничего строить на этом.
josh3736
@rlovtang: спасибо, я знаю разницу между сессией и локальным хранилищем. Согласно статье 24ways.org (первая ссылка на вопрос, решение №1), Chrome поддерживает только localStorage, а не sessionStorage. Возможно, это уже не так, поскольку эта статья была написана некоторое время назад.
Таурен
@ josh3736: да, я лично не хотел бы использовать куки и шестеренки. Я, конечно, не стал бы строить что-либо, полагаясь на него, но если бы это был резервный механизм хранения для кого-то, у кого он был установлен, и я не закодировал его напрямую, его можно было бы использовать.
Tauren
так что я на самом деле ошибался :) Не знал, что Chrome когда-то поддерживал localStorage, но не sessionStorage. По крайней мере, сейчас в Chrome есть поддержка обоих.
rlovtang

Ответы:

56

Я использую PersistJS ( репозиторий github ), который легко и прозрачно обрабатывает хранилище на стороне клиента для вашего кода. Вы используете единый 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 КБ).

josh3736
источник
10
Поддерживается ли PersistJS? Мне интересно, как это решает проблему, когда браузер обновляется и изменяется выбранный метод хранения (например, становится доступным локальное хранилище). Стала ли старая локация недоступна?
jcalfee314
2
По крайней мере, похоже, что он больше не находится в активной разработке.
Mahn
Это очень смелая библиотека. Не зная о максимальном размере в большинстве технологий, мы должны быть уверены, что наше приложение работает очень удачно ... Кроме того, это, похоже, только решение, если вы хотите сэкономить <64 КБ.
чувак
@julmot Вот для чего нужна библиотека. Обеспечьте удобство, отвлекаясь от утомительной работы. При достаточном количестве исследований и времени вы обычно можете понять, как заставить его работать, независимо от максимального размера. Конечно, похоже, что автор этого проекта решил, что это слишком ...
Уильям
Вы знаете, работает ли это с режимом приватного просмотра Safari? В настоящее время у меня проблема, когда localStorage не поддерживается в Safari Private Browsing как для macOS, так и для iOS.
Остин
61

Простой полифилл localStorage на основе чистого JS:

Демо: 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
Почему это не получает признания !? Спасибо чувак!
Роберт
4
:) - Мне не нравится добавлять целую библиотеку для всего, что мне нужно.
Амир Африди
2
разрешено ли в JavaScript определять var expiresлокально, а затем пользователя в другой области? в работеset
happy_marmoset
3
Просто хотел указать, что, хотя вы разрешаете установить срок действия cookie, localStorage никогда не истечет. Это может вызвать некоторые проблемы, если вы ищете что-то, срок действия которого истекает. Может быть полезно добавить дату истечения срока действия в локальное хранилище, а затем провести сравнение дат, чтобы увидеть, применимо ли оно еще. Конечно, я бы также сказал, что вы должны просто использовать cookie, если вам нужен срок действия. Но я думаю, что этот сценарий должен либо не допускать истечения срока действия, либо разрешать его для обоих, а не быть непоследовательным, как сейчас.
Ханна
1
@MohsinSaeed в приватном режиме, я думаю, браузер тоже не позволит вам создавать куки. superuser.com/questions/589248/…
Амир Африди
19

Вы видели страницу полифиллов в вики Modernizr?

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

найдите на этой странице раздел веб-хранилища, и вы увидите 10 возможных решений (по состоянию на июль 2011 г.).

удачи! отметка

Марк Ламмус
источник
1
Похоже, что ни один из них не работает в режиме частного / инкогнито (например, Safari или Chrome), так как их обходной путь создает файлы cookie, которые также отключены в этом режиме.
Alex Klaus
14

Ниже приведена приведенная в порядок версия ответа Амира Африди, в котором весь код инкапсулирован в локальной области.

Я удалил ссылки, которые создают глобальную retпеременную, а также удалил синтаксический анализ сохраненных строк «истина» и «ложь» на логические значения внутри BrowserStorage.get()метода, что могло вызвать проблемы, если кто-то пытается фактически сохранить строки «истина» или "ложный".

Поскольку 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);
        }
    };
})();
Стивен
источник
10

Лично я предпочитаю ampify.js . Раньше он работал у меня очень хорошо, и я рекомендовал его для всех нужд локального хранилища.

поддерживает IE 5+, Firefox 2+, Safari 4+, Chrome, Opera 10.5+, iPhone 2+, Android 2+ и предоставляет согласованный API для кросс-браузерной обработки хранилища

raidfive
источник
3

store.js использует userData и IE и localStorage в других браузерах.

  • Не пытается делать что-то слишком сложное

  • Никаких файлов cookie, flash или jQuery не требуется.

  • Чистый API.

  • 5 кб в сжатом виде

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

Микко Охтамаа
источник
1

Газонокосилка тоже кажется хорошей альтернативой

Кресло-газон вроде как диван, только меньше и снаружи. идеально подходит для мобильных приложений html5, которым требуется легкое, адаптивное, простое и элегантное решение для сохранения состояния.

  • коллекции. экземпляр шезлонга - это на самом деле просто массив объектов.
  • адаптивная настойчивость. базовое хранилище абстрагируется за согласованным интерфейсом.
  • подключаемое поведение коллекции. иногда нам нужны помощники по сбору, но не всегда.
j0k
источник
0

Есть реальное хранилище , которое использует Gears как запасной вариант.

Gaurav
источник
Спасибо. К сожалению, похоже, что он будет поддерживать меньше браузеров, чем предложение @josh3736 для PersistJS. Я все равно посмотрю на него и ценю предложение.
Tauren