Резервні рішення для локальної пам’яті HTML5 [закрито]


119

Я шукаю бібліотеки javascript і код, який може імітувати localStorageв браузерах, які не мають вбудованої підтримки.

В основному, я хотів би кодувати свій сайт, використовуючи localStorageдля зберігання даних, і знаю, що він все одно буде працювати в браузерах, які не підтримують його. Це означає, що бібліотека виявить, чи window.localStorageіснує, і використовуватиме її, якщо вона є. Якщо його не існує, він створив би якийсь резервний метод локального зберігання, створивши власну реалізацію в window.localStorageпросторі імен.

Поки що я знайшов такі рішення:

  1. Простий сеанс Реалізація сховища .
  2. Реалізація, яка використовує файли cookie (не в захваті від цієї ідеї).
  3. Додзьо dojox.storage , але це власну справу, на самому ділі не запасний варіант.

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

Будь ласка, поділіться будь-якими пов’язаними бібліотеками, ресурсами чи фрагментами коду, які ви знайшли! Мене особливо зацікавлять чисті рішення на основі JavaScript або jquery, але я здогадуюсь, що це малоймовірно.


sessionStorage та localStorage є частиною специфікації Web Storage ( dev.w3.org/html5/webstorage ). Різниця лише в тому, як довго браузер зберігатиме дані. Я думаю, ви не знайдете втілення, де у вас є одне, а не інше (але я не впевнений на 100%)
rlovtang

1
Варто згадати, що Gears був офіційно знецінений минулого лютого - я нічого не будував на цьому.
josh3736

@rlovtang: дякую, я знаю різницю між сеансом та місцевим сховищем. Відповідно до статті 24ways.org (перша посилання, про яку йдеться, рішення №1), Chrome підтримує лише localStorage, а не sessionStorage. Можливо, це вже не так, оскільки ця стаття була написана давно.
Таурен

@ josh3736: так, я особисто хотів би уникати використання файлів cookie та передач. Я, звичайно, не будував би на ній нічого надійного, але якщо це був резервний механізм зберігання для того, хто його встановив, і я не кодував його безпосередньо, це можна було б використовувати.
Таурен

тому я насправді помилявся :) Не знав, що колись Chrome мав підтримку localStorage, але не sessionStorage. Chrome має підтримку принаймні для обох.
rlovtang

Відповіді:


56

Я використовую PersistJS ( репозиторій github ), який обробляє сховища на стороні клієнта безперешкодно і прозоро для вашого коду. Ви використовуєте єдиний API і отримуєте підтримку для таких програм:

  • спалах: пам'ять, що зберігається у спалах 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 кБ).


10
Чи все ще підтримується PersistJS? Мені цікаво, як вона вирішує проблему, коли браузер оновлюється та змінюється обраний спосіб зберігання (скажімо, стає доступним місцеве зберігання). Старе місце розташування стає недоступним?
jcalfee314

2
Принаймні, це вже не схоже на те, що він вже в активному розвитку.
Ман

Це дуже смілива бібліотека. Не маючи жодних знань про максимальний розмір у більшості технологій, ми повинні констатувати, що наш додаток працює з великою долею ... Крім того, це, здається, є лише рішенням, якщо ви хочете заощадити <64 КБ.
чувак

@julmot Саме для цього потрібна бібліотека. Забезпечте зручність, відмовляючись від виснажливих речей. Маючи достатньо часу для дослідження та часу, ви можете зрозуміти, як змусити його працювати незалежно від максимального розміру. Звичайно, схоже, що автор цього проекту вирішив, що це занадто багато ...
Вільям

Чи знаєте ви, чи працює це в режимі приватного перегляду Safari? В даний час у мене виникає проблема, коли localStorage не підтримується в приватному перегляді Safari як на macOS, так і на iOS.
Остін

61

Чистий 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, місцеве зберігання ніколи не закінчується. Це може спричинити деякі проблеми, якщо ви шукаєте, що термін дії закінчується. Може бути корисним включити додавання терміну придатності до локального сховища, а потім зробити порівняння дат, щоб побачити, чи все ще застосовується. Звичайно, я б також стверджував, що вам слід просто використовувати печиво, якщо вам потрібен термін дії. Але я думаю, що цей сценарій повинен або не допускати закінчення терміну дії, або дозволити його обом, а не бути непослідовним, як це є зараз.
Ганна

1
@MohsinSaeed в приватному режимі, я думаю, що браузер не дозволить вам створювати файли cookie. superuser.com/questions/589248/…
Аамір Африді

19

Ви бачили сторінку полізаповнення у вікі Modernizr?

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

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

Щасти! Позначити


1
Здається, що жоден з них не працює в режимі приватного / анонімного режиму (наприклад, Safari або Chrome), оскільки їх вирішення створює файли cookie, які також відключені в цьому режимі.
Олексій Клаус

14

Нижче наведена приведена версія відповіді Ааміра Африді, яка зберігає весь код, інкапсульований у межах локальної сфери.

Я видалив посилання, які створюють глобальну retзмінну, а також видалив аналіз збережених рядків "true" та "false" на булеві значення в межахBrowserStorage.get() методу, що може спричинити проблеми, якщо намагається насправді зберегти рядки "true" або "помилковий".

Оскільки 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

Я особисто віддаю перевагу amplify.js . У минулому він працював дуже добре для мене, і я рекомендував його для всіх потреб місцевого зберігання.

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




1

Гаряча альтернатива теж здається хорошою альтернативою

галявинка - це сорт, як диван, за винятком менших та зовні. ідеально підходить для мобільних додатків html5, які потребують легкого, адаптивного, простого та елегантного рішення.

  • колекцій. екземпляр саду - це просто масив об'єктів.
  • адаптивна наполегливість. базовий магазин абстрагується за послідовним інтерфейсом.
  • поведінка підключення колекції. іноді нам потрібні помічники по збору, але не завжди.

0

Існує realstorage , який використовує Gears як резервний.


Дякую. На жаль, схоже, він би підтримував менше браузерів, ніж пропозиція @ josh3736 PersistJS. Я все-таки погляну на це і оціню пропозицію.
Таурен
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.