So erweitern Sie localStorage geräteübergreifend (ohne DB)

10

Ziel: Erweitern Sie meine bereits localStoragein meiner App implementierte , um wohl nicht lokal zu sein, denke ich.


Ich mag die Implementierung des Speicherns einfacher Benutzereinstellungen mit der lokalen Speicher-API. Ich habe dies für meine Bedürfnisse in einer Web-App, aber das einzige Problem ist, dass es lokal auf dem Computer / Browser ist, der verwendet / gespeichert wird. Ich habe dafür keinen Zugriff auf eine klassische MySQL-Stiltabelle. Ich möchte meinen lokalen Speicher erweitern oder anpassen, um ihn auf andere Browser zu übertragen. oder speichern Sie meine Benutzereinstellungen in Benutzer-JS-Objekten und JS-Objekteigenschaften.

  • Ich mag die Idee, einfach JSON- oder JavaScript-Objekte mit jedem Benutzer zu erstellen, wann immer es einen neuen Benutzer gibt, den Namen zu nehmen, ein Objekt oder object[key]mit dem Namen zu erstellen und die Standardeigenschaften der Feldeigenschaften zuerst zu verwenden, und Variablen werden gefüllt und oder überschrieben, wenn der Benutzer sie speichert.
  • Oder wenn das oben Genannte verpönt ist; Ich möchte meine localstorage-Implementierung beibehalten, da sie so gut funktioniert, und ein Plugin / eine Bibliothek / eine Erweiterung finden , mit der ich diese auch speichern und an verschiedenen Orten neu rendern kann. Daran muss man schon früher denken. Obwohl ich es gerne auf Kundenseite halten würde; Ich bin offen für eine node.js-Lösung sowie eine Python-Lösung. Ein einfacher Datenrahmen sollte ausreichend funktionieren.
  • Was ist mit dem Generieren einer Datei mit meinen localStorageDaten? Vielleicht eine CSV-Datei (dies sind nicht vertrauliche Daten) und muss sie wie meine aktualisiert werden localStorage?
doc Urlaub
quelle
2
Sie können dies nicht nur clientseitig tun. Um Benutzerinformationen in allen Browsern beizubehalten, benötigen Sie einen öffentlichen Server und speichern Informationen darauf. In der Regel erfolgt dies mithilfe einer Datenbank. Wenn Sie mySQL nicht verwenden möchten, gibt es andere Arten der Datenspeicherung. Firebase kommt Ihrer Vorstellung ziemlich nahe und ermöglicht das Speichern von Objekten beliebiger Struktur. (Außerdem ist JSON ein Textformat. Es gibt kein JSON-Objekt.)
Chris G
etwas ähnlich: stackoverflow.com/a/60279503/4845566 ?
Deblocker

Antworten:

3

Was ist mit SQLite?

Nur eine Datei auf Ihrem Server wie CSV. Senden einer http-Anfrage Zum Aktualisieren mit der SQL-Anweisung von knex oder ähnlichem nach dem Aktualisieren des lokalen Speichers auf der Clientseite.

Zumindest ist es besser als cvs, denke ich, weil Sie mehrere Tabellen definieren können, was skalierbarer und effizienter ist, wissen Sie, es ist eine Datenbank.

Kobako
quelle
2

Ich füge hier meine zwei Cent hinzu.


Datei exportieren / importieren (JSON, XML, CSV, TSV usw.)

Export:

Serialisieren Sie die Einstellungen und laden Sie sie als Datei herunter.

Importieren:

Öffnen Sie die exportierte / heruntergeladene serialisierte Einstellungsdatei.

Beispielcode:

<!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 (Abfragezeichenfolge)

Export:

Codieren Sie die Einstellungen in die Abfragezeichenfolge und kombinieren Sie sie mit der aktuellen URL als Hyperlink.

Importieren:

Besuchen Sie den Hyperlink, der eine Abfragezeichenfolge mit codierten Einstellungen enthält, und erkennen Sie dann JavaScript-Einstellungen und laden Sie sie aus der Abfragezeichenfolge.


Base64-codierte Daten

Export:

Serialisieren Sie die Einstellungen, codieren Sie sie als Base64-Zeichenfolge und kopieren Sie sie in die Zwischenablage.

Importieren:

Fügen Sie die Base64-Zeichenfolge aus der Zwischenablage in das Textfeld ein, um die Einstellungen zu dekodieren, zu deserialisieren und zu laden.


QR-Code

Export:

Codieren Sie die Einstellungen in die Abfragezeichenfolge und kombinieren Sie sie mit der aktuellen URL als Hyperlink. Generieren Sie dann ein QR-Code-Bild und zeigen Sie es an.

Importieren:

Scannen Sie das generierte QR-Code-Bild und besuchen Sie den Hyperlink automatisch.


HTTP-Server (Node.js) / Cloud-Speicher (AWS S3)

Export:

HTTP-POST zum Endpunkt automatisch beim Aktualisieren von Werten nach Benutzer-ID.

Importieren:

HTTP GET vom Endpunkt nach Benutzer-ID.


Extra: PouchDB

Die Datenbank, die synchronisiert!

PouchDB ist eine Open-Source-JavaScript-Datenbank, die von Apache CouchDB inspiriert wurde und für eine gute Ausführung im Browser ausgelegt ist.

PouchDB wurde entwickelt, um Webentwicklern beim Erstellen von Anwendungen zu helfen, die sowohl offline als auch online funktionieren. Es ermöglicht Anwendungen, Daten lokal zu speichern, während sie offline sind, und sie dann mit CouchDB und kompatiblen Servern zu synchronisieren, wenn die Anwendung wieder online ist, sodass die Daten des Benutzers unabhängig davon, wo sie sich das nächste Mal anmelden, synchron bleiben.

DK Dhilip
quelle
Danke für die Antwort. Das bisher beste; beim ersten Import / Export - könnte ich es so machen, dass der Benutzer einfach die Datei öffnen kann, damit die Einstellungen geladen werden? Wie könnte das funktionieren?
Doc Urlaub
1
Beispielcode für den Export / Import von JSON-Dateien hinzugefügt.
DK Dhilip
Ah ich sehe. Vielen Dank. Ich denke nur, dass das ein bisschen zu viel ist, um den Benutzer zu fragen. Wenn es eine Möglichkeit gäbe, könnte ich einen Hyperlink generieren und ihn vielleicht per E-Mail an sie senden. Ich denke, meine Daten enthalten zu viele Zeichen, um sie in eine URL-Abfragezeichenfolge einzufügen. Wie würde die QR-Code-Option gescannt?
Doc Holiday
Wenn Ihre Daten zu groß sind, um in die Abfragezeichenfolge zu passen, können Sie möglicherweise mit gzip / deflate plus Base64 experimentieren, um festzustellen, ob dadurch die Nutzlastgröße verringert und in die Abfragezeichenfolge aufgenommen werden kann. Ich weiß nicht, ob dies für Ihren Fall gut genug funktioniert, nur ein zufälliger Gedanke. Die QR-Code-Option kann von jedem Gerät mit einer Kamera gescannt oder die Bilddatei direkt gescannt werden (von einer normalen URL, einer Daten-URL, einer geöffneten Datei).
DK Dhilip
Um die Idee zur Reduzierung der Datengröße zu erweitern, können Sie auch versuchen, Ihre Daten manuell in ArrayBuffer zu serialisieren, um sie so klein wie möglich zu halten, und dann je nach Transportmethode die Base64-Codierung darauf anwenden.
DK Dhilip
2

Sie können die URL als Speicher verwenden, wenn Sie Ihre Benutzerparameter komprimieren.
Holen Sie sich die Parameter, die Sie speichern möchten> json> deflate> encode to base64> Push in die URL

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

onload: Holen Sie sich die Parameter aus der URL> dekodieren Sie von base64> aufblasen> analysieren Sie json

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

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

Der URL-Parameter ist ziemlich lang, aber zehnmal weniger als maximal verfügbar

Anton Tschukanow
quelle
Diese! Wenn ich jedoch meine lokalen Speicherdaten auf der Konsole protokolliere, sind es ~ 20.000 und ~ 8.000 Zeichen. Könnte ich so etwas noch machen?
Doc Holiday
1
Ich habe mit 160k Zeichen getestet. Nach dem Entleeren werden es 1600 Zeichen sein, sogar der IE wird ohne Probleme funktionieren (maximale URL-Länge für dh - 2048). Moderne Browser haben keine Einschränkung für die URL-Länge.
Anton Chukanov
Vielen Dank! Benötigt Pako eine Bibliothek oder so? Ich werde pako undefiniert
doc Urlaub
1
"Moderne Browser haben keine Einschränkung für die URL-Länge" ist eine falsche Annahme, bitte beziehen Sie sich darauf . Außerdem ist pako eine JavaScript-Bibliothek, die hier zu finden ist ( GitHub , cdnjs ). Beachten Sie zum Schluss auch, dass das Komprimierungsverhältnis je nach Dateninhalt variieren kann.
DK Dhilip
2

Speichern Sie die Einstellungen Ihres Benutzers im IPFS (InterPlanetary File System) https://ipfs.io/, anstatt localstorage zu verwenden.

Grundsätzlich würden Sie festlegen, dass die Einstellung ein Datenformat wie JSON ist, und es dann in eine Datei schreiben und an IPFS senden.

Sie benötigen eine Möglichkeit, um festzustellen, welche Daten an welchen Benutzer gesendet werden. Vielleicht könnten Sie einen Hash des Benutzernamens und des Passworts verwenden, um Ihre Dateien oder ähnliches zu benennen. Dann können Ihre Benutzer auf jedem Gerät immer auf ihre Inhalte zugreifen (solange sie ihr Passwort nicht vergessen haben).

Michael Babcock
quelle
1

Sie können eine aufgerufene Bibliothek verwenden, localForagedie im Grunde dieselbe API hat, mit der localStorageAusnahme, dass Sie komplexere Datenstrukturen (Arrays, Objekte) speichern können und außerdem nodejsStilrückrufe, Versprechen und unterstützen async await.

Hier ist ein Link zum Repository, wo Sie Beispielverwendungen finden und wie Sie es in Ihrem Projekt nach Ihren Wünschen implementieren können.

C. Gochev
quelle
Danke, das sieht ordentlich aus; Es sieht jedoch so aus, als hätte es die gleichen Einschränkungen für eine Datenbank wie für den normalen localStorage
doc-Urlaub
1

Der beste Weg, dies zu implementieren, ohne eine Datenbank für die gemeinsame Nutzung von Daten zu verwenden. Ich glaube, dass es sich um eine WebRTC- Lösung handelt. Ich habe es als eine Möglichkeit angesehen, dies zu tun, aber ich habe (zumindest für den Moment) keinen Code dafür, also mit einige Suche fand ich schon jemand tat es (nicht genau, aber mit einigen Verbesserungen wird es fertig sein) hier zum Beispiel, und dessen Teil dieses Artikels WebRTC ohne Signalisierungsserver

Hier ist noch eine Quelle: Datenkanal Basis Beispiel Demo

und auf github: Datenkanal Basisbeispiel

WebRTC ist nicht nur für Video- / Audio-Chats gedacht, sondern kann auch für Textnachrichten und die Zusammenarbeit bei der Textbearbeitung verwendet werden.

Diese Lösung wurde sogar in einer der Antworten hier erwähnt .

Ma'moun othman
quelle
0

Verwenden Sie Cookies oder haben Sie eine herunterladbare Datei, die Benutzer beim Zugriff auf einen anderen Browser zum Laden mitnehmen können. Sie können dies mit einer Text-, JSON- oder JavaScript-Datei mit Objektdaten tun.


quelle
Ich glaube, Cookies sind auch nur lokal?
Doc Holiday
Cookies von Drittanbietern können von mehreren Websites verwendet werden, wenn sie auf derselben "Quelle" basieren.
0

Sie können Redis verwenden . Es ist ein speicherinterner Datenstrukturspeicher, der als Datenbank verwendet wird. Sie können Ihre Daten in Schlüsselpaarformaten speichern. Es macht auch Ihre Anwendung schnell und effizient.

Deeksha Gupta
quelle
0

Offensichtlich ist der beste Ansatz die Verwendung einer Datenbank. Wenn Sie jedoch dazu neigen, eine Datenbank zu verwenden, besteht ein möglicher bester Ansatz darin, eine Kombination von Techniken zu verwenden, von denen ich glaube, dass Sie sie bereits angesprochen haben, damit ich Ihnen helfen kann, die Punkte hier zu verbinden.

Erforderliche Schritte:

  1. LocalStorage-API (da sie teilweise bereits für Sie funktioniert).
  2. Erstellen Sie einen Knoten- oder Python-Endpunkt (oder einen Endpunkt, mit dem Sie vertraut sind) für GET- und POST-Einstellungsdaten.
  3. Erstellen Sie eine userSettings.JSON-Datei auf Ihrem API-Server.

Anleitung:

Sie würden Ihren localStorage genauso verwenden, wie Sie ihn jetzt verwenden (aktueller Arbeitsstatus).

Um Benutzereinstellungen auf verschiedenen Geräten zu verschieben oder zu haben, wird eine userSettings.JSON-Datei (die als Dokumentendatenbank dient) zum Speichern und Importieren von Benutzereinstellungen verwendet.

Ihr API-Endpunkt wird zum Abrufen von Benutzereinstellungen verwendet, wenn in localStorage keine vorhanden sind. Aktualisieren Sie beim Aktualisieren der Einstellungen Ihren localStorage und POST / UPDATE die neuen Einstellungen in Ihrer userSettings.JSON-Datei mithilfe Ihres Endpunkts.

Ihr API-Endpunkt wird nur zum Verwalten (Lesen und Schreiben) der Datei userSettings.JSON verwendet. Sie benötigen eine Methode / Funktion, um Einstellungen in Ihrer Datei zu erstellen, zu aktualisieren und möglicherweise zu löschen. Wie Sie vielleicht bereits wissen, unterscheidet sich ein JSON-Dateiformat nicht wesentlich von einer MongoDB-Datenbank. In diesem Fall erstellen Sie nur die Methoden, die Sie zum Verwalten Ihrer Datei benötigen.

Ich hoffe das hilft!

mohammedabdulai
quelle
-1

Sie können dies ohne Datenbank beheben, aber ich würde es nicht empfehlen. Grundsätzlich haben Sie (Benutzer, localStorage) Paare, und wenn sich ein bestimmter Benutzer identifiziert, sollte sein localStorage in gewisser Weise bereitgestellt werden. Sie können Benutzer anweisen, ihre lokalen Speicher auf ihrem eigenen Computer zu speichern, müssen sie dann jedoch auf andere Computer kopieren, was arbeitsintensiv ist und niemals an Beliebtheit gewinnt. Man könnte einen Javascript-Block manuell in der Konsole seines Browsers ausführen, um sicherzustellen, dass localStorage über seine Daten verfügt, und das Kopieren der localStorage-Daten über Maschinen hinweg ist nur geringfügig einfacher als das manuelle Ausführen des Ganzen.

Sie können die codierten localStorage-Informationen in eine URL einfügen. Neben dem Problem der URL-Länge, das zu einem Problem werden kann, und den allgegenwärtigen Codierungsproblemen kann Ihr gesamtes localStorage von einem Dritten überwacht werden, der Zugriff auf Ihren Router hat. Ich weiß , Sie haben gesagt, dass die Daten nicht empfindlich sind, aber ich glaube, dass es nicht empfindlich ist noch . Sobald Benutzer dies verwenden, speichern sie, wenn es zweckmäßig ist, auch vertrauliche Daten, oder Ihre Kunden haben möglicherweise solche Aufgaben für Sie, oder Sie stellen möglicherweise fest, dass Sie dort Daten speichern müssen, die nicht zu 100% öffentlich sind.

Außerdem werden Sie in der Praxis mit sehr ernsten Problemen bei der Synchronisierung konfrontiert sein, das heißt, es ist alles schön, localStorage agnostisch zu machen, aber was ist dann die eigentliche Version? Wenn Sie regelmäßig an 10 verschiedenen Sitzungen arbeiten, wird die Synchronisierung der localStorages zu einem schwierigen Problem. Dies bedeutet, dass der localStorage mit einem Zeitstempel versehen werden muss.

Sie benötigen also einen zentralen Ort, einen Server zum Speichern der zuletzt gespeicherten localStorage-Version. Wenn Sie aus unbekannten Gründen von Datenbanken abgewendet werden, können Sie localStorages in Dateien speichern, die den Benutzer identifizieren, z

johndoe.json

Anschließend müssen Sie eine Exportfunktion implementieren, die den aktuellen JSON des Benutzers an den Server sendet und in einer Datei und einer Importfunktion speichert. Dadurch wird die für den Benutzer gespeicherte Datei heruntergeladen und sichergestellt, dass localStorage aktualisiert wird entsprechend. Sie können beide auch zusammen ausführen und eine Synchronisation implementieren.

Dies ist bisher einfach, aber was ist, wenn der Benutzer bereits einige nützliche Daten in seinem lokalen localStorage und auch auf dem Server hat? Der einfachste Ansatz besteht darin, einen mit dem anderen zu überschreiben, aber welcher? Wenn wir importieren, wird der lokale überschrieben, beim Exportieren wird der auf dem Server überschrieben. Wenn wir synchronisieren, wird der ältere überschrieben.

In einigen Fällen möchten Sie jedoch zwei localStorages desselben Benutzers zusammenführen.

neue Elemente

Ich glaube, wenn ein Element neu ist, sollte auf irgendeine Weise bekannt sein, dass es in dieser Sitzung erstellt wurde. Dies ist hilfreich zu wissen, da dies bedeutet, dass dieses neue Element in der anderen Sitzung, mit der wir zusammenführen, nicht entfernt wurde und daher ist es intuitiv, es hinzuzufügen.

Elementänderungen

Wenn dasselbe Element in beiden Fällen unterschiedlich ist, sollte die neuere Version Vorrang haben.

entfernte Elemente

Der interessante Fall ist, wenn es in einer Sitzung entfernt und in der anderen aktualisiert wurde. In diesem Fall sollte sich die neuere Änderung durchsetzen.


Trotz Ihrer Bemühungen können Benutzer (und auch Ihre Software) immer noch Probleme haben. Daher ist es sinnvoll, jede Sitzung auf Ihrem Server zu sichern.

Lajos Arpad
quelle