Comment étendre localStorage sur des appareils (sans DB)


10

Objectif: étendre mon déjà implémenté localStoragedans mon application, pour être bien, non local je suppose.


J'aime l'implémentation de l'enregistrement de paramètres utilisateur simples avec l'API de stockage local. J'ai ce travail pour mes besoins dans une application web, mais le seul problème est qu'il est local sur cette machine / navigateur utilisé / enregistré. Je n'ai pas accès à une table de style MySQL classique pour cela. Je souhaite étendre ou adapter mon stockage local pour le transférer vers d'autres navigateurs; ou stocker mes paramètres utilisateur dans les objets JS utilisateur et les propriétés d'objet JS.

  • J'aime l'idée de simplement créer des objets JSON ou JavaScript avec chaque utilisateur, chaque fois qu'il y a un nouvel utilisateur, prenez le nom, créez un objet ou object[key]avec le nom, et avoir les propriétés par défaut des variables de champ au début, et les variables sont remplies et ou remplacé lorsque l'utilisateur les enregistre.
  • Ou si ce qui précède est mal vu; aimerait conserver mon implémentation de stockage local car elle fonctionne si bien et trouver un plugin / bibliothèque / extension d'une sorte qui me permette également de l'enregistrer et de le restituer à différents endroits; cela a dû être pensé auparavant. Même si j'adorerais le garder côté client; Je suis ouvert à une solution node.js ainsi qu'à une solution python, une simple trame de données devrait fonctionner assez.
  • Qu'en est-il de la génération d'un fichier avec mes localStoragedonnées? Peut-être un fichier .csv (il s'agit de données non sensibles) et le faire mettre à jour comme le mien localStorage?

2
Vous ne pouvez pas faire cela côté client uniquement. Pour conserver les informations utilisateur sur les navigateurs, vous avez besoin d'un serveur public et y stocker des informations. En général, cela se fait à l'aide d'une base de données; si vous ne souhaitez pas utiliser mySQL, il existe d'autres types de stockage de données. Firebase est assez proche de ce que vous imaginez, il vous permet de stocker des objets de structure arbitraire. (aussi, JSON est un format texte. Il n'y a rien de tel qu'un objet JSON)
Chris G

quelque peu similaire à cela: stackoverflow.com/a/60279503/4845566 ?
deblocker

Réponses:


3

Et l'utilisation de sqlite?

Un seul fichier sur votre serveur comme csv. Envoi d'une requête http Pour la mettre à jour en utilisant l'instruction SQL par knex ou quelque chose comme ça après avoir mis à jour le stockage local côté client.

Au moins, c'est mieux que cvs, je pense parce que vous pouvez définir plusieurs tables, ce qui est plus évolutif et plus efficace, vous savez, c'est une base de données.


2

J'ajoute mes deux cents ici.


Fichier d'exportation / importation (JSON, XML, CSV, TSV, etc.)

Exportation:

Sérialisez les paramètres et téléchargez-les sous forme de fichier.

Importation:

Ouvrez le fichier de paramètres sérialisés exporté / téléchargé.

Exemple de code:

<!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 (chaîne de requête)

Exportation:

Encodez les paramètres dans la chaîne de requête et combinez-les avec l'URL actuelle en tant que lien hypertexte.

Importation:

Visitez l'hyperlien contenant la chaîne de requête avec les paramètres encodés, puis JavaScript détecte et charge les paramètres de la chaîne de requête.


Données encodées en Base64

Exportation:

Sérialisez les paramètres, puis codez-les en tant que chaîne Base64, puis copiez-les dans le presse-papiers.

Importation:

Collez la chaîne Base64 du presse-papiers dans la zone de texte pour décoder, désérialiser et charger les paramètres.


QR Code

Exportation:

Encodez les paramètres dans la chaîne de requête et combinez-les avec l'URL actuelle en tant que lien hypertexte. Générez ensuite une image de code QR et affichez-la.

Importation:

Scannez l'image du code QR généré et visitez l'hyperlien automatiquement.


Serveur HTTP (Node.js) / Stockage cloud (AWS S3)

Exportation:

HTTP POST pour endpoint automatiquement lors de la mise à jour des valeurs, par ID utilisateur.

Importation:

HTTP GET à partir du point de terminaison par ID utilisateur.


Extra: PouchDB

La base de données qui se synchronise!

PouchDB est une base de données JavaScript open source inspirée d' Apache CouchDB qui est conçue pour fonctionner correctement dans le navigateur.

PouchDB a été créé pour aider les développeurs Web à créer des applications qui fonctionnent aussi bien hors ligne qu'en ligne. Il permet aux applications de stocker des données localement hors ligne, puis de les synchroniser avec CouchDB et des serveurs compatibles lorsque l'application est de nouveau en ligne, en gardant les données de l'utilisateur synchronisées, peu importe où il se connecte.


Merci pour la réponse. Le meilleur encore; avec la première importation / exportation - pourrais-je faire en sorte que l'utilisateur puisse simplement ouvrir le fichier pour que les paramètres se chargent? Comment cela pourrait-il fonctionner?
vacances

1
Ajout d'un exemple de code pour l'exportation / l'importation de fichiers JSON.
DK Dhilip

Ah, je vois. Je vous remercie. Je pense juste que c'est un peu trop demander à l'utilisateur. S'il y avait un moyen, je peux générer un lien hypertexte et le leur envoyer par e-mail peut-être. Je pense que mes données contiennent trop de caractères pour mettre dans une chaîne de requête URL. Comment serait analysée l'option de code QR?
vacances doc

Si vos données sont trop volumineuses pour tenir dans la chaîne de requête, vous pourriez peut-être expérimenter avec gzip / deflate plus Base64 pour voir si cela peut réduire la taille de la charge utile et l'inclure dans la chaîne de requête? Je ne sais pas si cela fonctionnera assez bien pour votre cas, juste une pensée aléatoire. Pour l'option de code QR, il peut être numérisé par n'importe quel appareil équipé d'un appareil photo ou numériser le fichier image directement (à partir d'une URL ordinaire, d'une URL de données, d'un fichier ouvert).
DK Dhilip

Pour développer l'idée de réduction de la taille des données, vous pouvez également essayer de sérialiser manuellement vos données dans ArrayBuffer pour les rendre aussi petites que possible, puis lui appliquer le codage Base64 en fonction de la méthode de transport.
DK Dhilip

2

Vous pouvez utiliser l'URL comme stockage si vous zippez vos paramètres utilisateur.
obtenir les paramètres que vous souhaitez stocker> json> dégonfler> encoder en base64> pousser dans l'URL

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

onload: récupérer les paramètres depuis l'url> décoder depuis base64> gonfler> analyser json

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

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

Le paramètre d'URL sera assez long, mais 10 fois moins que le maximum disponible


Cette! Cependant, lorsque je console mon journal de données de stockage local, c'est ~ 20k et ~ 8k en caractères. Puis-je encore faire quelque chose comme ça?
vacances doc le

1
J'ai testé avec 160k caractères. Ce sera 1600 caractères après le dégonflage, même IE fonctionnera sans problème (longueur d'url maximale pour ie - 2048). Les navigateurs modernes n'ont aucune limitation quant à la longueur de l'url.
Anton Chukanov

Merci! pako nécessite-t-il une bibliothèque ou quelque chose? Je reçois pako undefined
vacances doc le

1
« Les navigateurs modernes ne sont pas limités à la longueur de l' URL » est une hypothèse fausse, s'il vous plaît se référer à ce . De plus, pako est une bibliothèque JavaScript que vous pouvez trouver ici ( GitHub , cdnjs ). Enfin, veuillez également noter que le taux de compression peut varier en fonction du contenu des données.
DK Dhilip

2

Au lieu d'utiliser localstorage, stockez les paramètres de votre utilisateur dans le système de fichiers InterPlanetary (IPFS) https://ipfs.io/

Fondamentalement, vous mettriez leur paramètre est un format de données comme JSON, puis l'écrire dans un fichier et le pousser vers IPFS.

Vous aurez besoin d'un moyen d'identifier quelles données vont à quel utilisateur. Vous pourriez peut-être utiliser un hachage du nom d'utilisateur et du mot de passe pour nommer vos fichiers ou quelque chose comme ça. Ensuite, votre utilisateur serait toujours en mesure d'accéder à son contenu sur n'importe quel appareil (tant qu'il n'a pas oublié son mot de passe).


1

Vous pouvez utiliser une bibliothèque appelée localForagequi a fondamentalement la même API que localStoragesauf qu'elle vous permet de stocker des structures de données plus complexes (tableaux, objets) et prend également en charge le nodejsrappel de style, les promesses et async await.

Voici un lien vers le référentiel où vous pouvez trouver des exemples d'utilisation et comment l'implémenter dans votre projet comme vous le souhaitez.


Merci qui a l'air bien; mais on dirait qu'il a les mêmes limitations à une base de données que localStorage normal
doc vacances

1

La meilleure façon de l'implémenter sans utiliser de base de données pour partager des données, je crois que c'est basé sur une solution WebRTC , je l'ai pensé comme un moyen de le faire mais je n'ai pas de code pour cela (du moins pour l'instant), donc avec certaines recherches, j'ai trouvé que quelqu'un l'avait déjà fait (pas exactement, mais avec quelques ajustements, il sera prêt) ici par exemple, et sa partie de cet article webrtc sans serveur de signalisation

voici une autre source: exemple de démonstration de base du canal de données

et sur github: exemple de base du canal de données

WebRTC n'est pas seulement pour le chat vidéo / audio, il peut également être utilisé dans la messagerie texte et la collaboration dans l'édition de texte.

Cette solution est même mentionnée dans l'une des réponses ici .


0

Utilisez des cookies ou disposez d'un fichier téléchargeable que les utilisateurs peuvent emporter avec eux à charger lorsqu'ils accèdent à un autre navigateur. Vous pouvez le faire avec un fichier texte, JSON ou JavaScript avec des données d'objet.


Je pense que les cookies sont uniquement locaux?
vacances doc le

Les cookies tiers peuvent être utilisés par plusieurs sites Web s'ils s'appuient sur la même «source».

0

Vous pouvez utiliser Redis . Il s'agit d'un magasin de structure de données en mémoire, utilisé comme base de données. Vous pouvez stocker vos données dans des formats de paires de clés. Cela rend également votre application rapide et efficace.


0

De toute évidence, la meilleure approche consiste à utiliser une base de données. Cependant, si vous êtes enclin à utiliser une base de données, la meilleure approche possible consiste à utiliser une combinaison de techniques que je crois que vous avez déjà abordées, je vais donc vous aider à relier les points ici.

Étapes nécessaires:

  1. API LocalStorage (car cela fonctionne déjà partiellement pour vous).
  2. Créez un noeud ou un point de terminaison Python (ou ce que vous êtes à l'aise avec) pour obtenir les données de paramètres GET et POST.
  3. Créez un fichier userSettings.JSON sur votre serveur API.

Instructions:

Vous utiliseriez votre localStorage de la même manière que vous l'utilisez maintenant (état de fonctionnement actuel).

Afin de déplacer ou d'avoir des paramètres utilisateur sur différents appareils, un fichier userSettings.JSON (servant de base de données de documents) sera utilisé pour stocker et importer les paramètres utilisateur.

Votre point de terminaison API serait utilisé pour obtenir les paramètres utilisateur s'il n'en existe aucun dans localStorage. Lors de la mise à jour des paramètres, mettez à jour votre localStorage puis POST / UPDATE les nouveaux paramètres dans votre fichier userSettings.JSON à l'aide de votre point de terminaison.

Votre point de terminaison API ne sera utilisé que pour gérer (lire et écrire) le fichier userSettings.JSON. Vous aurez besoin d'une méthode / fonction pour créer, mettre à jour et peut-être supprimer les paramètres de votre fichier. Comme vous le savez peut-être déjà, un format de fichier JSON n'est pas très différent d'une base de données MongoDB. Dans ce cas, vous créez simplement les méthodes dont vous avez besoin pour gérer votre fichier.

J'espère que ça aide!


-1

Vous pouvez résoudre ce problème sans base de données, mais je ne le recommanderais pas. Fondamentalement, vous avez des paires (utilisateur, localStorage) et lorsqu'un utilisateur donné s'identifie, son localStorage doit être fourni d'une manière. Vous pouvez dire aux utilisateurs de stocker leurs stockages locaux sur leur propre machine, mais ils devront ensuite les copier sur d'autres machines, ce qui demande beaucoup de travail et ne gagnera jamais en popularité. On pourrait exécuter manuellement un morceau Javascript dans la console de leur navigateur pour s'assurer que localStorage a leurs données et avoir à copier les machines localStorage sur les machines n'est que légèrement plus facile que de faire manuellement le tout.

Vous pouvez mettre les informations localStorage encodées dans une URL, mais en plus du problème de la longueur de l'URL, qui pourrait devenir un problème et des problèmes d'encodage toujours présents, tout votre localStorage peut être surveillé par un tiers ayant accès à votre routeur. Je sais que vous avez dit que les données n'étaient pas sensibles, mais je vous crois qu'elles ne le sont pas encore . Mais une fois que les utilisateurs l'utiliseront, si cela est pratique, ils stockeront également des données sensibles ou, vos clients pourraient avoir de telles tâches pour vous, ou même vous pourriez réaliser que vous devez y stocker des données qui ne sont pas 100% publiques.

En plus de cela, dans la pratique, vous serez confronté à de très graves problèmes de synchronisation, c'est-à-dire qu'il est agréable de rendre localStorage agnostique, mais alors, quelle est la vraie version? Si vous travaillez régulièrement sur 10 sessions différentes, la synchronisation des stockages locaux devient alors un problème difficile. Cela signifie que le localStorage doit être horodaté.

Ainsi, vous aurez besoin d'un emplacement central, d'un serveur pour stocker la dernière version de localStorage enregistrée. Si vous êtes évité par les bases de données pour des raisons inconnues, vous pouvez stocker localStorages dans des fichiers qui identifient l'utilisateur, comme

johndoe.json

puis, vous devrez implémenter une fonction d'exportation, qui enverra le JSON actuel de l'utilisateur au serveur et l'enregistrera dans un fichier et une fonction d'importation, qui téléchargera le fichier stocké pour l'utilisateur et s'assurera que localStorage est mis à jour en conséquence. Vous pouvez également faire les deux ensemble en implémentant une synchronisation.

C'est simple jusqu'à présent, mais que se passe-t-il si l'utilisateur dispose déjà de données utiles dans son localStorage local et sur le serveur? L'approche la plus simple consiste à remplacer l'une par l'autre, mais laquelle? Si nous importons, alors le local est remplacé, si vous exportez, celui sur le serveur est remplacé, si nous synchronisons, alors l'ancien est remplacé.

Cependant, dans certains cas, vous souhaitez fusionner deux stockages locaux du même utilisateur, donc:

nouveaux éléments

Je crois que si un élément est nouveau, il faut savoir d'une certaine manière qu'il a été créé dans cette session, ce qui est utile à savoir, car cela signifie que sur l'autre session avec laquelle nous fusionnons, ce nouvel élément n'a pas été supprimé et il est donc intuitif de l'ajouter.

changements d'éléments

Si le même élément est différent dans les deux cas, la nouvelle version devrait prévaloir.

éléments supprimés

Le cas intéressant est quand dans une session il a été supprimé et dans l'autre il a été mis à jour. Dans ce cas, je pense que le changement le plus récent devrait prévaloir.


Cependant, malgré tous vos efforts, les utilisateurs peuvent toujours gâcher (et votre logiciel aussi), il est donc logique de sauvegarder chaque session sur votre serveur.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.