Як поширити localStorage на пристрої (без БД)


10

Мета: розширити вже реалізований localStorageу моєму додатку, щоб було добре, не локально, мабуть.


Мені подобається реалізація збереження простих налаштувань користувача за допомогою локального API зберігання. У мене це працює для моїх потреб у веб-програмі, але єдина проблема полягає в тому, що він локальний для того, щоб машина / браузер використовувалася / зберігалася. У мене немає доступу до класичної таблиці стилів MySQL для цього. Я хотів би розширити або адаптувати свій локальний сховище для перенесення до інших браузерів; або зберігати мої налаштування користувача у об'єктах JS користувача та у власних об'єктах JS.

  • Мені подобається ідея просто створити об’єкти JSON або JavaScript з кожним користувачем, коли є новий користувач, візьміть ім’я, створіть об'єкт або object[key]з ім'ям, і спочатку мають поля змінних властивостей поля за замовчуванням, а змінні стануть заповненими та або переосмислюється, коли користувач їх зберігає.
  • Або якщо зазначене вище хмуриться; хотів би зберегти мою локальну сховище, оскільки вона працює так добре, і знайти якийсь плагін / бібліотеку / розширення , яке дозволяє мені також зберегти це і повторно відтворити в різних місцях; про це треба було думати раніше. Хоча я хотів би тримати його на стороні клієнта; Я відкритий до рішення node.js, а також до рішення python, простий тип файлів даних повинен працювати достатньо.
  • Що щодо створення файлу з моїми localStorageданими? Можливо, файл .csv (це нечутливі дані) і оновити його, як і мої localStorage?

2
Ви не можете робити це лише на стороні клієнта. Для збереження інформації про користувачів у веб-переглядачах вам потрібен загальнодоступний сервер і зберігання на ньому інформації. Зазвичай це робиться за допомогою бази даних; якщо ви не хочете використовувати mySQL, є інші типи зберігання даних. Firebase досить близька до того, що ви уявляєте, дозволяє зберігати об'єкти довільної структури. (також JSON - це текстовий формат. Немає такого поняття, як об’єкт JSON)
Chris G

дещо схоже на це: stackoverflow.com/a/60279503/4845566 ?
деблокер

Відповіді:


3

Що з використанням sqlite?

Лише один файл на вашому сервері, як csv. Надсилання запиту http Щоб оновити його за допомогою оператора SQL за допомогою knex або чогось подібного після оновлення локального сховища на стороні клієнта.

Принаймні, це краще, ніж резюме, я думаю, тому що ви можете визначити кілька таблиць, що є більш масштабованим і більш ефективним, ви знаєте, це база даних.


2

Я додаю сюди свої два центи.


Експорт / імпорт файлу (JSON, XML, CSV, TSV тощо)

Експорт:

Серіалізуйте налаштування та завантажте його як файл.

Імпорт:

Відкрийте експортований / завантажений серіалізований файл налаштувань.

Приклад коду:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Settings Export/Import Demo</title>
</head>

<body>
    <div id="display"></div> <br>
    <button onclick="exportSettings();">Export</button>

    <button onclick="resetSettings();">Reset</button> <br><br>
    File to import: <input id="file-input" type="file" accept="application/json"> <br>
    <button onclick="importSettings();">Import</button>
    <script>

        function exportSettings() {
            var json = getSettingsAsJSON();
            var blob = new Blob([json], { type: "application/json" });
            var linkElement = document.createElement("a");

            linkElement.href = URL.createObjectURL(blob);
            linkElement.download = "ThisIsMySettings";

            document.body.appendChild(linkElement);

            linkElement.click();

            document.body.removeChild(linkElement);
        }

        function importSettings() {
            var fileInput = document.getElementById("file-input");

            if (fileInput.files.length > 0) {
                var jsonFile = fileInput.files[0];

                var fileReader = new FileReader();

                fileReader.onload = function (e) {
                    var json = e.target.result;

                    try {
                        var settings = JSON.parse(json);

                        if (settings.hasOwnProperty("userId")) {
                            localStorage["myapp_user_id"] = settings.userId;
                        }

                        if (settings.hasOwnProperty("hello")) {
                            localStorage["myapp_hello"] = settings.hello;
                        }

                        if (settings.hasOwnProperty("data")) {
                            localStorage["myapp_data"] = settings.data;
                        }

                        displaySettings();
                    } catch (ex) {
                        console.error(ex);

                        alert("Error occured while importing settings!");
                    }
                };

                fileReader.readAsText(jsonFile);
            }
        }

        function resetSettings() {
            localStorage["myapp_user_id"] = Math.floor(Math.random() * 100000) + 1;
            localStorage["myapp_hello"] = "Hello World!";
            localStorage["myapp_data"] = JSON.stringify([1, 3, 3, 7]);

            displaySettings();
        }

        function displaySettings() {
            var json = getSettingsAsJSON();

            document.getElementById("display").innerText = json;
        }

        function getSettingsAsJSON() {
            return JSON.stringify({
                userId: localStorage["myapp_user_id"],
                hello: localStorage["myapp_hello"],
                data: localStorage["myapp_data"]
            });
        }

        resetSettings();
    </script>
</body>

</html>

URL-адреса (рядок запиту)

Експорт:

Кодуйте параметри в рядок запиту та поєднуйте з поточною URL-адресою як гіперпосилання.

Імпорт:

Відвідайте гіперпосилання, що містить рядок запиту із закодованими налаштуваннями, а потім JavaScript визначить та завантажує параметри з рядка запиту.


Кодовані дані Base64

Експорт:

Серіалізуйте налаштування, потім кодуйте його як рядок Base64, а потім скопіюйте у буфер обміну.

Імпорт:

Вставте рядок Base64 з буфера обміну в текстове поле для декодування, деаріалізації та завантаження налаштувань.


QR-код

Експорт:

Кодуйте параметри в рядок запиту та поєднуйте з поточною URL-адресою як гіперпосилання. Потім генеруйте зображення та відображайте QR-код.

Імпорт:

Скануйте створене зображення QR-коду та відвідайте гіперпосилання автоматично.


HTTP-сервер (Node.js) / хмарне зберігання (AWS S3)

Експорт:

HTTP POST для автоматичної кінцевої точки під час оновлення значень за ідентифікатором користувача.

Імпорт:

HTTP GET з кінцевої точки за ідентифікатором користувача.


Додатково: PouchDB

База даних, яка синхронізується!

PouchDB - це база даних JavaScript з відкритим кодом, натхненна Apache CouchDB, яка створена для роботи в браузері.

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


Дякуємо за відповідь. Найкращий ще; з першим імпортом / експортом - я міг би зробити це, щоб користувач міг просто відкрити файл для завантаження налаштувань? Як це могло працювати?
свято док

1
Додано приклад коду для експорту / імпорту файлів JSON.
DK Dhilip

А, бачу. Дякую. Я просто думаю, що це небагато запитати у користувача. Якби був спосіб, я можу генерувати гіперпосилання та, можливо, надіслати його електронною поштою. Я думаю, що мої дані містять занадто багато символів для введення рядка запиту URL. Як сканувати варіант QR-коду?
свято док.

Якщо ваші дані занадто великі, щоб вмістити в рядок запиту, можливо, ви могли б поекспериментувати з gzip / deflate plus Base64, щоб побачити, чи може вона зменшити розмір корисної навантаження та включити її в рядок запиту? Я не знаю, чи це спрацює досить добре для вашої справи, просто випадкова думка. Що стосується параметра QR-коду, його можна сканувати на будь-яких пристроях з камерою або сканувати файл зображення безпосередньо (зі звичайної URL-адреси, URL-адреси даних, відкритого файлу).
DK Dhilip

Щоб розширити ідею зменшення розміру даних, ви також можете спробувати вручну серіалізувати свої дані в ArrayBuffer, щоб зробити їх якомога меншим, а потім застосувати до нього кодування Base64 залежно від способу транспортування.
DK Dhilip

2

Ви можете використовувати URL як сховище, якщо ви поштовуєте параметри користувача.
отримати парами, які ви хочете зберегти> json> deflate> кодувати до base64> натисніть на URL

const urlParam = btoa(pako.deflate(JSON.stringify(getUser()), { to: 'string' }));

onload: отримайте параметри з URL-адреси> декодування від base64> inflate> parse json

const user = JSON.parse(pako.inflate(atob(urlParam), { to: 'string' }));

https://jsfiddle.net/chukanov/q4heL8gu/44/

Параметр URL буде досить довгим, але в 10 разів менше максимального доступного


Це! Однак, коли я консольно записую свої дані локального зберігання, це символи ~ 20k та ~ 8k. Чи можу я все-таки зробити щось подібне?
свято док.

1
Я тестував 160k символів. Це буде 1600 символів після дефляції, навіть IE працюватиме без проблем (максимальна довжина URL-адреси, тобто - 2048). Сучасні веб-переглядачі не мають обмежень щодо довжини URL-адреси.
Антон Чуканов

Дякую! Пако потрібна бібліотека чи щось таке? Я отримую pako undefined
doc свято

1
"Сучасні браузери не обмежують довжину URL-адреси" - помилкове припущення, будь ласка, зверніться до цього . Також pako - це бібліотека JavaScript, яку можна знайти тут ( GitHub , cdnjs ). Нарешті, врахуйте також, що коефіцієнт стиснення може бути різним залежно від вмісту даних.
ДК Діліп

2

Замість того, щоб використовувати локальне зберігання, зберігайте налаштування свого користувача в міжпланетній файловій системі (IPFS) https://ipfs.io/

В основному, ви б встановили їх налаштування такого формату даних, як JSON, а потім записати його у файл та надіслати його на IPFS.

Вам знадобиться спосіб визначити, які дані надходять до якого користувача. Можливо, ви можете використовувати хеш імені користувача та пароля, щоб назвати свої файли чи щось подібне. Тоді ваш користувач завжди зможе отримати доступ до їх вмісту на будь-якому пристрої (до тих пір, поки він не забуде свій пароль).


1

Ви можете використовувати бібліотеку під назвою, localForageяка в основному має той же API, localStorageза винятком того, що вона дозволяє зберігати складніші структури даних (масиви, об'єкти), а також підтримує nodejsзворотний виклик стилю, обіцянки та async await.

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


Завдяки тому, що виглядає акуратно; але схоже, що він має ті самі обмеження для БД, що і звичайний localStorage
свято док.

1

Найкращий спосіб реалізувати це, не використовуючи базу даних для обміну даними, я вважаю, що це рішення, засноване на WebRTC , я вважав це як спосіб зробити це, але у мене немає коду для цього (принаймні поки що), так що з деякий пошук Я знайшов, що хтось це вже робив (не точно, але з деякими налаштуваннями він буде готовий) ось, наприклад, і його частина цієї статті webrtc без сигналізаційного сервера

ось ще одне джерело: демонстраційний базовий приклад каналу даних

і на github: базовий приклад каналу даних

WebRTC не тільки для відео / аудіо чату, він також може бути використаний для обміну текстовими повідомленнями та співпраці в редагуванні тексту.

Це рішення навіть згадувалося в одній з відповідей тут .


0

Використовуйте файли cookie або файл, який можна завантажити, який користувачі можуть взяти із собою для завантаження під час доступу до іншого браузера. Це можна зробити за допомогою текстового, JSON або JavaScript-файлу з даними об’єкта.


Я вважаю, печиво також є лише місцевим?
свято док.

Файли cookie третіх сторін можуть використовуватися на декількох веб-сайтах, якщо вони покладаються на одне і те ж "джерело".

0

Можна використовувати Redis . Це сховище структури даних в пам'яті, яке використовується як база даних. Ви можете зберігати свої дані у форматах ключових пар. Це також робить вашу програму швидкою та ефективною.


0

Очевидно, що найкращим підходом є використання бази даних. Однак якщо ви схильні до використання бази даних, то можливим найкращим підходом є використання комбінації методів, які, я вважаю, ви вже торкнулися, тому я допоможу вам підключити точки тут.

Необхідні кроки:

  1. API LocalStorage (оскільки він частково працює для вас).
  2. Створіть кінцеву точку Node або Python (або що вам подобається) для даних налаштувань GET та POST.
  3. Створіть на своєму сервері API файл userSettings.JSON.

Інструкції:

Ви б використовували локальний зберігання так само, як і зараз (поточний робочий стан).

Щоб переміщати або мати налаштування користувача на різних пристроях, для зберігання та імпорту параметрів користувача буде використовуватися файл userSettings.JSON (служить як база даних документів).

Ваша кінцева точка API буде використовуватися для отримання параметрів користувача GET, якщо таких немає в localStorage. Під час оновлення налаштувань оновіть локальнуStorage, а потім POST / UPDATE нові налаштування у файлі userSettings.JSON, використовуючи кінцеву точку.

Ваша кінцева точка API буде використовуватися лише для підтримки (читання та запису) файлу userSettings.JSON. Вам знадобиться метод / функція для створення, оновлення та, можливо, видалення налаштувань у вашому файлі. Як ви вже можете знати, формат файлу JSON мало чим відрізняється від бази даних MongoDB. У цьому випадку ви просто створюєте методи, необхідні для управління вашим файлом.

Я сподіваюся, що це допомагає!


-1

Ви можете вирішити це без бази даних, але я б не рекомендував це. В основному у вас є (користувач, localStorage) пари, і коли даний користувач ідентифікує себе, його / її localStorage має надаватися певним чином. Ви можете сказати користувачам зберігати свої місцеві сховища на власній машині, але тоді їм доведеться скопіювати їх на інші машини, що трудомістко і ніколи не набере популярності. Можна було вручну запустити фрагмент Javascript у консолі свого браузера, щоб переконатися, що localStorage має свої дані, а копіювати локальні сховища на всіх машинах лише трохи легше, ніж робити всю справу вручну.

Ви можете розмістити закодовану інформацію localStorage в URL-адресі, але, крім проблеми довжини URL-адреси, яка може стати проблемою, і наявних проблем із кодуванням, ваш весь localStorage може контролюватися третьою стороною, маючи доступ до маршрутизатора. Я знаю , що ви сказали , що дані не чутливі, але я вважаю, що це не відчутно ще . Але коли користувачі використовуватимуть це, якщо це зручно, вони також зберігатимуть конфіденційні дані, або ваші клієнти можуть мати такі завдання для вас, або навіть ви зрозумієте, що вам потрібно зберігати там дані, які не є на 100% загальнодоступними.

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

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

johndoe.json

а потім вам потрібно буде реалізувати функцію експорту, яка надішле поточний JSON користувача на сервер і збереже його у файл та функцію імпорту, яка завантажить збережений для користувача файл та забезпечить оновлення localStorage відповідно. Ви також можете зробити це разом, здійснивши синхронізацію.

Наразі це просто, але що робити, якщо користувач вже має корисні дані всередині свого локального локального сховища та на сервері? Найпростіший підхід - перекрити одне з іншим, але який? Якщо ми імпортуємо, то локальний - це переопределено, якщо експортується, то той на сервері буде переопрацьований, якщо ми синхронізуємо, то старіший буде замінений.

Однак у деяких випадках потрібно об'єднати два локальнихмагазини одного користувача, так що:

нові елементи

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

зміни елементів

Якщо один і той же елемент відрізняється в двох випадках, тоді повинна переважати нова версія.

вилучені елементи

Цікавий випадок, коли в одному сеансі його було видалено, а в іншому оновлено. У цьому випадку я думаю, що новіші зміни повинні переважати.


Однак, незважаючи на ваші зусилля, користувачі можуть все-таки зіпсувати (і ваше програмне забезпечення) речі, тому резервне копіювання кожного сеансу на вашому сервері має сенс.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.