Come estendere localStorage su tutti i dispositivi (senza DB)


10

Obiettivo: estendere il mio già implementato localStoragenella mia app, per essere bene, non locale suppongo.


Mi piace l'implementazione del salvataggio di semplici impostazioni utente con l'API di archiviazione locale. Ho funzionato per le mie esigenze in un'app Web, ma l'unico problema è che è locale per quel computer / browser utilizzato / salvato. Per questo non ho accesso a una classica tabella di stile MySQL. Vorrei estendere o adattare la mia memoria locale per il trasferimento su altri browser; o memorizzare le mie impostazioni utente negli oggetti JS utente e nelle proprietà dell'oggetto JS.

  • Mi piace l'idea di creare semplicemente oggetti JSON o JavaScript con ciascun utente, ogni volta che c'è un nuovo utente, prendere il nome, creare un oggetto o object[key]con il nome e avere inizialmente le proprietà predefinite delle proprietà del campo e le variabili vengono popolate e o ignorato quando l'utente li salva.
  • O se quanto sopra è disapprovato; vorrei mantenere la mia implementazione di localstorage in quanto funziona così bene e trovare un plugin / libreria / estensione di qualche tipo che mi consenta di salvare anche questo e ri-renderizzare in diverse posizioni; questo è stato pensato prima. Anche se mi piacerebbe mantenerlo lato client; Sono aperto a una soluzione node.js e alla soluzione Python, un semplice frame di dati dovrebbe funzionare abbastanza.
  • Che ne dici di generare un file con i miei localStoragedati? Forse un file .csv (si tratta di dati non sensibili) e lo aggiorno come il mio localStorage?

2
Non puoi fare solo questo lato client. Per rendere persistenti le informazioni dell'utente su tutti i browser è necessario un server pubblico e archiviare informazioni su di esso. In genere questo viene fatto utilizzando un database; se non si desidera utilizzare mySQL, esistono altri tipi di archiviazione dei dati. Firebase è abbastanza vicino a quello che immagini, ti permette di conservare oggetti di struttura arbitraria. (inoltre, JSON è un formato di testo. Non esiste un oggetto JSON)
Chris G

Risposte:


3

Che dire dell'utilizzo di sqlite?

Solo un file sul tuo server come CSV. Invio di una richiesta http Per aggiornarla utilizzando l'istruzione SQL di knex o qualcosa del genere dopo aver aggiornato lo store locale sul lato client.

Almeno è meglio di cvs, penso che sia possibile definire diverse tabelle, che è più scalabile e più efficiente, sai, è un database.


2

Sto aggiungendo i miei due centesimi qui.


Esporta / importa file (JSON, XML, CSV, TSV, ecc.)

Esportare:

Serializza le impostazioni e scaricalo come file.

Importare:

Aprire il file delle impostazioni serializzate esportato / scaricato.

Codice di esempio:

<!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 (stringa di query)

Esportare:

Codifica le impostazioni nella stringa di query e combinale con l'URL corrente come collegamento ipertestuale.

Importare:

Visita il collegamento ipertestuale che contiene una stringa di query con impostazioni codificate, quindi JavaScript rileva e carica le impostazioni dalla stringa di query.


Dati codificati Base64

Esportare:

Serializza le impostazioni quindi codificale come stringa Base64, quindi copia negli Appunti.

Importare:

Incolla la stringa Base64 dagli Appunti nella casella di testo per decodificare, deserializzare e caricare le impostazioni.


QR Code

Esportare:

Codifica le impostazioni nella stringa di query e combinale con l'URL corrente come collegamento ipertestuale. Quindi generare un'immagine del codice QR e visualizzarla.

Importare:

Scansiona l'immagine del codice QR generato e visita automaticamente il collegamento ipertestuale.


Server HTTP (Node.js) / Cloud Storage (AWS S3)

Esportare:

POST HTTP per endpoint automaticamente durante l'aggiornamento dei valori, per ID utente.

Importare:

HTTP GET dall'endpoint per ID utente.


Extra: PouchDB

Il database che si sincronizza!

PouchDB è un database JavaScript open source ispirato ad Apache CouchDB progettato per funzionare bene all'interno del browser.

PouchDB è stato creato per aiutare gli sviluppatori Web a creare applicazioni che funzionano sia offline che online. Consente alle applicazioni di archiviare i dati localmente in modalità offline, quindi di sincronizzarli con CouchDB e server compatibili quando l'applicazione è di nuovo online, mantenendo sincronizzati i dati dell'utente indipendentemente dal successivo accesso.


Grazie per la risposta. Il migliore in assoluto; con la prima importazione / esportazione - potrei farlo in modo che l'utente possa semplicemente aprire il file per caricare le impostazioni? Come potrebbe funzionare?
vacanza doc

1
Aggiunto codice di esempio per esportazione / importazione file JSON.
DK Dhilip,

Ah, capisco. Grazie. Penso solo che sia un po 'troppo chiedere all'utente. Se ci fosse un modo, posso generare un collegamento ipertestuale e inviarlo via e-mail a loro forse. Penso che i miei dati contengano troppi caratteri per inserire una stringa di query URL. Come verrebbe scansionata l'opzione del codice QR?
vacanza doc

Se i tuoi dati sono troppo grandi per adattarsi alla stringa di query, forse potresti sperimentare gzip / deflate più Base64 per vedere se può ridurre la dimensione del payload e includerlo nella stringa di query? Non so se questo funzionerà abbastanza bene per il tuo caso, solo un pensiero casuale. Per l'opzione del codice QR, potrebbe essere scansionato da qualsiasi dispositivo con una fotocamera o scansionare direttamente il file di immagine (da un normale URL, URL di dati, file aperto).
DK Dhilip,

Per espandere l'idea di riduzione della dimensione dei dati, è anche possibile provare a serializzare manualmente i dati in ArrayBuffer per renderli il più piccoli possibile e quindi applicare la codifica Base64 ad esso in base al metodo di trasporto.
DK Dhilip,

2

Puoi utilizzare l'URL come archivio se comprimi i parametri utente.
ottieni i parametri che vuoi memorizzare> json> deflate> codifica in base64> push nell'URL

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

onload: ottiene i parametri dall'URL> decodifica da base64> gonfia> parse json

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

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

Il parametro url sarà piuttosto lungo, ma 10 volte inferiore al massimo disponibile


Questo! Tuttavia, quando consento i miei dati di archivio locale, sono ~ 20k e ~ 8k in caratteri. Potrei ancora fare qualcosa del genere?
vacanza doc

1
Ho testato con 160k caratteri. Saranno 1600 caratteri dopo lo sgonfiaggio, anche IE funzionerà senza problemi (lunghezza massima dell'URL per es. - 2048). I browser moderni non hanno limiti per la lunghezza dell'URL.
Anton Chukanov,

Grazie! pako richiede una libreria o qualcosa del genere? Sto diventando pako indefinito
doc holiday

1
"I browser moderni non hanno limiti per la lunghezza dell'URL" è un presupposto falso, fare riferimento a questo . Inoltre, pako è una libreria JavaScript che può essere trovata qui ( GitHub , cdnjs ). Infine, tieni presente che il rapporto di compressione può variare a seconda del contenuto dei dati.
DK Dhilip,

2

Invece di utilizzare localstorage, memorizzare le impostazioni dell'utente nel file system InterPlanetary (IPFS) https://ipfs.io/

Fondamentalmente, dovresti mettere la loro impostazione in un formato di dati come JSON e quindi scriverlo su file e inviarlo a IPFS.

Avrai bisogno di un modo per identificare quali dati vanno a quale utente. Forse potresti usare un hash di nome utente e password per nominare i tuoi file o qualcosa del genere. Quindi il tuo utente sarà sempre in grado di accedere al suo contenuto su qualsiasi dispositivo (purché non abbia dimenticato la password).


1

È possibile utilizzare una libreria denominata localForageche ha fondamentalmente la stessa API di localStoragetranne che consente di archiviare strutture di dati più complesse (array, oggetti) e supporta anche nodejscallback di stile, promesse e async await.

Ecco un link al repository in cui puoi trovare esempi di utilizzo e come implementarlo nel tuo progetto come preferisci.


Grazie sembra pulito; ma sembra che abbia le stesse limitazioni a un DB del normale localStorage
festività del documento

1

Il modo migliore per implementarlo senza utilizzare il database per la condivisione dei dati, credo che sia basato sulla soluzione WebRTC , l'ho pensato come un modo per farlo, ma non ho codice per esso (almeno per ora), quindi con qualche ricerca ho trovato qualcuno già fatto (non esattamente, ma con alcune modifiche sarà pronto) qui per esempio, e la sua parte di questo articolo webrtc senza un server di segnalazione

ecco un'altra fonte: demo di esempio di base del canale dati

e su github: esempio di base del canale dati

WebRTC non è solo per la chat video / audio, ma può anche essere utilizzato nella messaggistica di testo e nella collaborazione per l'editing di testo.

Questa soluzione è stata menzionata anche in una delle risposte qui .


0

Utilizzare i cookie o disporre di un file scaricabile che gli utenti possono portare con sé per caricare quando accedono a un altro browser. Puoi farlo con un file di testo, JSON o JavaScript con dati oggetto.


Credo che anche i cookie siano solo locali?
vacanza doc

I cookie di terze parti possono essere utilizzati da più siti Web se si basano sulla stessa "fonte".

0

Puoi usare Redis . Si tratta di un archivio di strutture di dati in memoria, utilizzato come database. È possibile archiviare i dati in formati di coppie di chiavi. Inoltre, rende l'applicazione veloce ed efficiente.


0

Ovviamente l'approccio migliore è usare un database. Tuttavia, se sei propenso a utilizzare un database, un possibile approccio migliore è utilizzare una combinazione di tecniche che credo tu abbia già toccato, quindi ti aiuterò a collegare i punti qui.

Passaggi necessari:

  1. API LocalStorage (poiché funziona già parzialmente per te).
  2. Costruisci un nodo o un endpoint Python (o quello che ti piace) con i dati delle impostazioni GET e POST.
  3. Crea un file userSettings.JSON sul tuo server API.

Istruzioni:

Utilizzeresti localStorage nello stesso modo in cui lo stai utilizzando ora (stato di lavoro attuale).

Per spostare o impostare le impostazioni utente su diversi dispositivi, verrà utilizzato un file userSettings.JSON (che funge da database dei documenti) per archiviare e importare le impostazioni utente.

Il tuo endpoint API verrebbe utilizzato per OTTENERE le impostazioni utente se non ne esiste alcuna in localStorage. All'aggiornamento delle impostazioni, aggiornare localStorage e quindi POST / UPDATE le nuove impostazioni nel file userSettings.JSON utilizzando l'endpoint.

L'endpoint API verrà utilizzato solo per conservare (leggere e scrivere) il file userSettings.JSON. Avrai bisogno di un metodo / funzione per creare, aggiornare e forse eliminare le impostazioni nel tuo file. Come forse già saprai, un formato di file JSON non è molto diverso da un database MongoDB. In questo caso stai solo creando i metodi necessari per gestire il tuo file.

Spero che questo possa essere d'aiuto!


-1

Puoi risolverlo senza un database, ma non lo consiglierei. Fondamentalmente hai coppie (utente, archivio locale) e quando un determinato utente si identifica, il suo archivio locale dovrebbe essere fornito in un certo modo. Puoi dire agli utenti di archiviare i loro archivi locali sulla propria macchina, ma poi dovranno copiarli su altre macchine, che sono ad alta intensità di lavoro e non guadagneranno mai popolarità. Si potrebbe eseguire manualmente un blocco Javascript nella console del proprio browser per assicurarsi che localStorage abbia i propri dati e che dover copiare localStorage attraverso le macchine sia solo leggermente più semplice che fare manualmente tutto.

È possibile inserire le informazioni localStorage codificate in un URL, ma oltre al problema della lunghezza dell'URL, che potrebbe diventare un problema e i problemi di codifica sempre presenti, l'intero localStorage può essere monitorato da una terza parte, con accesso al router. So che hai detto che i dati non sono sensibili, ma ti credo che non siano ancora sensibili . Ma una volta che gli utenti lo useranno, se è conveniente, memorizzeranno anche i dati sensibili o, i tuoi clienti potrebbero avere tali compiti per te, o potresti anche renderti conto che devi archiviare lì dati che non sono pubblici al 100%.

Oltre a questi, in pratica affronterai seri problemi di sincronizzazione, ovvero è bello rendere agnostico localStorage, ma qual è la versione reale? Se lavori regolarmente su 10 sessioni diverse, la sincronizzazione degli archivi locali diventa un problema difficile. Ciò significa che localStorage deve essere timestamp.

Quindi, avrai bisogno di un posto centrale, un server per archiviare l'ultima versione salvata localStorage. Se si è evitati dai database per alcuni motivi sconosciuti, è possibile memorizzare localStorage all'interno di file che identificano l'utente, come

johndoe.json

e quindi, dovrai implementare una funzione di esportazione, che invierà l'attuale JSON dell'utente al server e lo salverà in un file e una funzione di importazione, che scaricherà il file archiviato per l'utente e assicurerà che localStorage venga aggiornato di conseguenza. Puoi anche fare le due cose insieme, implementando una sincronizzazione.

Questo è semplice finora, ma cosa succede se l'utente ha già alcuni dati utili all'interno del suo archivio locale locale e sul server? L'approccio più semplice è quello di sovrascrivere l'uno con l'altro, ma quale? Se stiamo importando, quello locale viene sovrascritto, se si esporta, quindi quello sul server viene ignorato, se sincronizziamo, il precedente viene ignorato.

Tuttavia, in alcuni casi si desidera unire due archivi locali dello stesso utente, quindi:

nuovi elementi

Credo che se un elemento è nuovo, dovrebbe essere noto in qualche modo che è stato creato in questa sessione, il che è utile sapere, perché ciò significa che nell'altra sessione con cui ci stiamo unendo, questo nuovo elemento non è stato rimosso e quindi è intuitivo aggiungerlo.

l'elemento cambia

Se lo stesso elemento è diverso nei due casi, dovrebbe prevalere la versione più recente.

elementi rimossi

Il caso interessante è quando in una sessione è stato rimosso e nell'altra è stato aggiornato. In questo caso, penso che dovrebbe prevalere il cambiamento più recente.


Tuttavia, nonostante i tuoi migliori sforzi, gli utenti potrebbero comunque fare confusione (e anche il tuo software), quindi il backup di ogni sessione sul tuo server ha senso.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.