Как распространить localStorage на устройства (без БД)

10

Цель: расширить мой уже реализованный localStorageв моем приложении, чтобы быть хорошо, не локально, я думаю.


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

  • Мне нравится идея просто создавать объекты JSON или JavaScript с каждым пользователем, когда бы ни появился новый пользователь, взять имя, создать объект или object[key]с именем, и сначала свойства переменных поля будут иметь значения по умолчанию, а переменные заполнятся и / или перезаписывается, когда пользователь сохраняет их.
  • Или если вышеупомянутое осуждается; хотел бы сохранить мою реализацию localstorage, так как она работает так хорошо, и найти какой-нибудь плагин / библиотеку / расширение, которое позволит мне также сохранить это и перерисовать в разных местах; об этом нужно думать раньше. Хотя я хотел бы сохранить это на стороне клиента; Я открыт как для решения node.js, так и для решения на python, простой тип данных должен работать достаточно.
  • Как насчет создания файла с моими localStorageданными? Возможно файл .csv (это не конфиденциальные данные) и он обновляется, как мой localStorage?
док праздник
источник
2
Вы не можете сделать это только на стороне клиента. Чтобы сохранить информацию о пользователях в разных браузерах, вам нужен общедоступный сервер и хранить на нем информацию. Обычно это делается с использованием базы данных; если вы не хотите использовать mySQL, существуют другие типы хранилищ данных. Firebase довольно близок к тому, что вы себе представляете, он позволяет хранить объекты произвольной структуры. (также JSON - это текстовый формат. Нет такого понятия, как объект JSON)
Крис Г.
несколько похоже на это: stackoverflow.com/a/60279503/4845566 ?
деблокировщик

Ответы:

3

Как насчет использования sqlite?

Просто один файл на вашем сервере, как CSV. Отправка http-запроса Чтобы обновить его с помощью оператора SQL с помощью knex или чего-то подобного после обновления локального хранилища на стороне клиента.

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

kobako
источник
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.
ДК Дилип
Ах я вижу. Спасибо. Я просто думаю, что это очень много, чтобы спросить у пользователя. Если бы был способ, я мог бы создать гиперссылку и отправить ее по электронной почте им, возможно. Я думаю, что мои данные содержат слишком много символов, чтобы поместить их в строку запроса URL. Как будет сканироваться опция QR-кода?
праздник
Если ваши данные слишком велики, чтобы поместиться в строке запроса, возможно, вы могли бы поэкспериментировать с gzip / deflate плюс Base64, чтобы увидеть, может ли он уменьшить размер полезной нагрузки и включить в строку запроса? Я не знаю, будет ли это работать достаточно хорошо для вашего случая, просто случайная мысль. Для параметра QR-кода его можно сканировать на любых устройствах с камерой или сканировать файл изображения напрямую (с обычного URL-адреса, URL-адреса данных, открытого файла).
ДК Дилип
Чтобы расширить идею уменьшения размера данных, вы можете также попытаться вручную сериализовать ваши данные в ArrayBuffer, чтобы сделать их как можно меньшими, а затем применить к ним кодировку Base64 в зависимости от метода транспорта.
ДК Дилип
2

Вы можете использовать URL как хранилище, если вы заархивировали свои пользовательские параметры.
получите параметры, которые вы хотите сохранить> json> deflate> encode to 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 раз меньше максимально доступного

Антон Чуканов
источник
Эта! Однако, когда я консольный журнал, мои данные localalstorage это ~ 20k и ~ 8k в символах. Могу ли я сделать что-то подобное?
док праздник
1
Я тестировал 160к символов. После deflate оно будет составлять 1600 символов, даже IE будет работать без проблем (максимальная длина URL для - 2048). Современные браузеры не имеют ограничений по длине URL.
Антон Чуканов
Спасибо! Пако требует библиотеки или что-то? Я получаю Пако undefined
Праздник
1
«Современные браузеры не имеют ограничений по длине URL» - ложное предположение, пожалуйста, обратитесь к этому . Также pako - это библиотека JavaScript, которую можно найти здесь ( GitHub , cdnjs ). Наконец, обратите внимание, что степень сжатия может варьироваться в зависимости от содержимого данных.
ДК Дилип
2

Вместо использования localalstorage сохраните настройки вашего пользователя в Межпланетной файловой системе (IPFS) https://ipfs.io/

По сути, вы бы поместили их настройки в такой формат данных, как JSON, а затем записали их в файл и отправили в IPFS.

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

Майкл Бэбкок
источник
1

Вы можете использовать библиотеку с именем, localForageкоторая в основном имеет тот же API, что и localStorageза исключением того, что она позволяет хранить более сложные структуры данных (массивы, объекты), а также поддерживает nodejsстиль обратного вызова, обещания и async await.

Вот ссылка на репозиторий, где вы можете найти примеры использования и как реализовать его в своем проекте так, как вам нравится.

C.Gochev
источник
Спасибо, что выглядит аккуратно; но похоже, что он имеет те же ограничения на БД, что и обычный localStorage
doc holiday
1

Лучший способ реализовать это без использования базы данных для обмена данными, я считаю, что это основано на решении WebRTC , я подумал об этом, как об этом, но у меня нет кода для него (по крайней мере, на данный момент), так что с какой-то поиск, который я нашел, кто-то уже сделал (не совсем, но с некоторыми изменениями, он будет готов) здесь, например, и его часть этой статьи webrtc без сервера сигнализации

вот еще один источник: демонстрационный пример канала данных

и на github: базовый пример канала данных

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

Это решение даже упоминается в одном из ответов здесь .

Мамун Отман
источник
0

Используйте куки-файлы или загрузите файл, который пользователи могут взять с собой для загрузки при доступе к другому браузеру. Это можно сделать с помощью текстового файла, файла JSON или JavaScript с данными объекта.


источник
Я полагаю, что куки только локальные?
праздник
Сторонние файлы cookie могут использоваться несколькими веб-сайтами, если они используют один и тот же «источник».
0

Вы можете использовать Redis . Это хранилище структуры данных в памяти, используемое в качестве базы данных. Вы можете хранить свои данные в форматах пары ключей. Это также делает ваше приложение быстрым и эффективным.

Дикша гупта
источник
0

Очевидно, что лучший подход заключается в использовании базы данных. Тем не менее, если вы склонны использовать базу данных, возможно, лучше всего использовать комбинацию техник, которые, я полагаю, вы уже затронули, поэтому я помогу вам соединить точки здесь.

Необходимые шаги:

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

Инструкции:

Вы бы использовали ваш localStorage так же, как вы используете его сейчас (текущее рабочее состояние).

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

Ваша конечная точка API будет использоваться для получения пользовательских настроек, если в localStorage их нет. При обновлении настроек обновите localStorage и затем поместите / обновите новые настройки в файле userSettings.JSON, используя вашу конечную точку.

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

Надеюсь, это поможет!

mohammedabdulai
источник
-1

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

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

Помимо этого, на практике вы столкнетесь с очень серьезными проблемами синхронизации, то есть все хорошо, чтобы сделать localStorage независимым, но тогда, какова реальная версия? Если вы регулярно работаете над 10 различными сессиями, то синхронизация localStorages становится трудной проблемой. Это означает, что localStorage должен иметь метку времени.

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

johndoe.json

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

Пока это просто, но что, если у пользователя уже есть некоторые полезные данные внутри его локального localStorage, а также на сервере? Самый простой подход - переопределить одно на другое, но какой? Если мы импортируем, то локальный переопределяется, если экспортируется, то перезаписывается тот, что на сервере, если мы синхронизируемся, то перезаписывается более старый.

Однако в некоторых случаях вы хотите объединить два локальных хранилища одного и того же пользователя, поэтому:

новые элементы

Я полагаю, что если элемент является новым, он должен каким-то образом знать, что он был создан в этом сеансе, что полезно знать, поскольку это означает, что в другом сеансе, с которым мы объединяемся, этот новый элемент не был удален и, следовательно, добавить его интуитивно понятно.

изменения элемента

Если один и тот же элемент отличается в обоих случаях, то более новая версия должна иметь преимущественную силу.

удаленные элементы

Интересный случай, когда в одном сеансе он был удален, а в другом - обновлен. В этом случае я думаю, что более новое изменение должно преобладать.


Тем не менее, несмотря на все ваши усилия, пользователи могут все еще испортить (и ваше программное обеспечение) вещи, поэтому имеет смысл создавать резервные копии каждой сессии на вашем сервере.

Лайос Арпад
источник