localStorageをデバイス間で拡張する方法(DBなし)


10

目標:localStorage自分のアプリに既に実装されているものを拡張して、ローカルでないと思います。


ローカルストレージAPIで簡単なユーザー設定を保存する実装が好きです。私はこれをWebアプリのニーズに合わせて機能させていますが、唯一の問題は、使用/保存されているそのマシン/ブラウザーに対してローカルであることです。このための古典的なMySQLスタイルのテーブルにアクセスできません。ローカルストレージを他のブラウザに引​​き継ぐように拡張または調整したいと思います。または、ユーザーのJSオブジェクトとJSオブジェクトのプロパティにユーザー設定を保存します。

  • 各ユーザーでJSONまたはJavaScriptオブジェクトを作成するだけのアイデアが好きです。新しいユーザーが存在する場合は常に、名前を取得し、オブジェクトまたは名前を作成し、object[key]最初にフィールドプロパティのデフォルト変数を設定します。ユーザーがそれらを保存するとオーバーライドされます。
  • または、上記が嫌われている場合; 私のlocalstorage実装がうまく機能していることを維持し、これを保存して別の場所に再レンダリングできるようにするプラグイン/ライブラリ/拡張機能を見つけたいと思います。これは以前に考えられてきました。私はそれをクライアント側に保ちたいですが; 私はnode.jsソリューションとpythonソリューションを利用できますが、単純な種類のデータフレームで十分機能するはずです。
  • localStorageデータでファイルを生成するのはどうですか?おそらく.csvファイル(これは機密データでlocalStorageはありません)で、私のように更新しますか?

2
これをクライアント側だけで行うことはできません。ブラウザー間でユーザー情報を保持するには、パブリックサーバーが必要であり、そこに情報を保存します。通常、これはデータベースを使用して行われます。mySQLを使用したくない場合は、他のタイプのデータストレージがあります。Firebaseはご想像のとおり、任意の構造のオブジェクトを保存できます。(また、JSONはテキスト形式です。JSONオブジェクトのようなものはありません)
Chris G

回答:


3

sqliteの使用についてはどうですか?

サーバー上のcsvのような1つのファイルのみ。httpリクエストの送信クライアント側のlocalstorageを更新した後、knexなどのSQLステートメントを使用してリクエストを更新します。

少なくともcvsよりも優れていると思います。複数のテーブルを定義できます。これは、よりスケーラブルで、より効率的です。データベースです。


2

ここに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)/ Cloud Storage(AWS S3)

書き出す:

ユーザーID別に、値を更新するときにエンドポイントへのHTTP POSTを自動的に行います。

インポート:

ユーザーIDによるエンドポイントからのHTTP GET。


追加:PouchDB

同期するデータベース!

PouchDBは、Apache CouchDBに触発されたオープンソースのJavaScriptデータベースであり、ブラウザー内で適切に実行されるように設計されています。

PouchDBは、Web開発者がオンラインと同様にオフラインでも機能するアプリケーションを構築できるように作成されました。これにより、アプリケーションはオフラインでデータをローカルに保存し、アプリケーションがオンラインに戻ったときにCouchDBと互換性のあるサーバーと同期できるため、ユーザーが次にログインした場所に関係なくユーザーのデータを同期できます。


ご回答ありがとうございます。まだ最高です。最初のインポート/エクスポートで-ユーザーが設定を読み込むためにファイルを開くだけで済むようにすることができますか?それはどのように機能しますか?
文書休日

1
JSONファイルのエクスポート/インポートのサンプルコードを追加しました。
DK Dhilip

ああ、分かった。ありがとうございました。それはユーザーに尋ねるには少々多すぎると思います。ハイパーリンクを生成して電子メールで送信できる方法があったら。データに含まれる文字が多すぎて、URLクエリ文字列に入力できないと思います。QRコードオプションはどのようにスキャンされますか?
文書休日

データが大きすぎてクエリ文字列に収まらない場合、おそらくgzip / deflateと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分の1になります


この!ただし、ローカルストレージデータをコンソールログに記録すると、文字で〜20kおよび〜8kです。このままでもいいですか?
ドク休日

1
160k文字でテストしました。デフレート後は1600文字になります。IEでも問題なく機能します(ieの最大URL長-2048)。最新のブラウザでは、URLの長さに制限はありません。
アントンチュカノフ

ありがとう!パコは図書館や何かが必要ですか?私は未定義のパコを取得しています
ドキュメント休日

1
「最新のブラウザではURLの長さに制限はありません」は誤った仮定です。これを参照しください。また、pakoは、ここ(GitHubcdnjs)にあるJavaScriptライブラリです。最後に、圧縮率はデータの内容によって異なる可能性があることにも注意してください。
DK Dhilip

2

localstorageを使用する代わりに、ユーザーの設定をInterPlanetary File System(IPFS)https://ipfs.io/に保存します

基本的に、それらの設定はJSONのようなデータ形式であり、それをファイルに書き込んでIPFSにプッシュします。

どのデータがどのユーザーに送信されるかを識別する方法が必要になります。たぶん、ユーザー名とパスワードのハッシュを使用して、ファイルなどに名前を付けることができます。そうすれば、ユーザーはいつでも(パスワードを忘れない限り)どのデバイスでもコンテンツにアクセスできます。


1

より複雑なデータ構造(配列、オブジェクト)を格納でき、スタイルコールバック、約束、およびもサポートすることを除いlocalForageて、基本的に同じAPIを持つライブラリを使用localStorageできます。nodejsasync await

リポジトリへのリンクは次のとおりです 。ここには、使用例の例と、プロジェクトに好きなように実装する方法があります。


きれいに見えてありがとう。しかし、DBには通常のlocalStorageと同じ制限があるようです
文書休日

1

データを共有するためにデータベースを使用せずにこれを実装する最良の方法、それはWebRTCソリューションベースであると思います。それを行う方法として考えましたが、(少なくとも今のところ)コードはありません。いくつかの私は、誰かがすでにそれをやった検索(正確には、いくつかの調整と、それは準備ができていない)、ここで例えば、この記事のその一部シグナリングサーバなしのWebRTC

これがもう1つのソースです:データチャネルの基本的なサンプルデモ

とgithub上:データチャネルの基本的な例

WebRTCはビデオ/オーディオチャットだけでなく、テキストメッセージングやテキスト編集のコラボレーションにも使用できます。

この解決策は、ここの答えの1つでも言及されています


0

Cookieを使用するか、ダウンロード可能なファイルを用意して、ユーザーが別のブラウザーにアクセスするときにロードして読み込むことができます。これは、オブジェクトデータを含むテキスト、JSON、またはJavaScriptファイルで実行できます。


クッキーもローカルだけだと思いますか?
ドキュメント休日

サードパーティのCookieは、同じ「ソース」に依存している場合、複数のWebサイトで使用できます。

0

Redisを使用できます。これは、データベースとして使用されるインメモリデータ構造ストアです。データはキーペア形式で保存できます。また、アプリケーションを高速かつ効率的にします。


0

明らかに、最良のアプローチはデータベースを使用することです。ただし、データベースを使用する傾向がある場合、考えられる最善のアプローチは、すでに触れたと思われる手法の組み合わせを使用することです。そのため、ここで点をつなぐ手助けをします。

必要な手順:

  1. LocalStorage API(すでに部分的に機能しているため)。
  2. GETおよびPOST設定データのノードまたはPython(または使いやすいもの)エンドポイントを構築します。
  3. APIサーバーにuserSettings.JSONファイルを作成します。

手順:

現在使用しているのと同じ方法(現在の作業状態)でlocalStorageを使用します。

異なるデバイス間でユーザー設定を移動または保持するには、userSettings.JSONファイル(ドキュメントデータベースとして機能)を使用して、ユーザー設定を保存およびインポートします。

localStorageに何も存在しない場合、APIエンドポイントを使用してユーザー設定を取得します。設定の更新時に、localStorageを更新し、エンドポイントを使用してuserSettings.JSONファイルの新しい設定をPOST / UPDATEします。

APIエンドポイントは、userSettings.JSONファイルを維持(読み取りおよび書き込み)するためにのみ使用されます。ファイルの設定を作成、更新、削除するためのメソッド/関数が必要になります。すでにご存じかもしれませんが、JSONファイル形式はMongoDBデータベースと大差ありません。この場合、ファイルの管理に必要なメソッドを作成するだけです。

これが役に立てば幸いです!


-1

これはデータベースがなくても解決できますが、お勧めしません。基本的には(user、localStorage)のペアがあり、特定のユーザーが自分自身を識別した場合、そのlocalStorageを提供する必要があります。ローカルストレージを自分のマシンに保存するようにユーザーに指示することはできますが、それを他のマシンにコピーする必要があります。これは労働集約的であり、人気を獲得することはありません。ブラウザのコンソールでJavascriptチャンクを手動で実行して、localStorageにデータがあり、マシン間でlocalStorageをコピーする必要があるのは、手動で全体を実行するよりも少しだけ簡単です。

エンコードされたlocalStorage情報をURLに入れることができますが、URLの長さの問題(これが問題になる可能性があり、常にエンコードの問題が発生する可能性がある)に加えて、ルーターにアクセスできるサードパーティがlocalStorage全体を監視できます。私はあなたがデータが機密性がないと言ったのを知っています、しかし私はそれがまだ機密性がないとあなたを信じます。ただし、ユーザーがこれを使用すると、便利であれば、機密データも保存されます。または、クライアントにそのようなタスクがある場合や、100%公開されていないデータをそこに保存する必要があることに気付く場合もあります。

これらに加えて、実際には同期の非常に深刻な問題に直面します。つまり、localStorageを無視することはすべて良いことですが、実際のバージョンは何ですか?10の異なるセッションで定期的に作業する場合、localStorageの同期は困難な問題になります。つまり、localStorageにはタイムスタンプを付ける必要があります。

したがって、中央の場所、つまり最後に保存されたlocalStorageバージョンを保存するサーバーが必要になります。不明な理由でデータベースを回避する場合は、次のように、ユーザーを識別するファイル内にlocalStorageを保存できます。

johndoe.json

次に、エクスポート機能を実装する必要があります。これは、ユーザーの現在のJSONをサーバーに送信し、ファイルに保存します。インポート機能は、ユーザー用に保存されたファイルをダウンロードし、localStorageが確実に更新されるようにします。それに応じて。2つを同時に実行して、同期を実装することもできます。

これはこれまでのところ簡単ですが、ユーザーがローカルlocalStorage内とサーバー上にすでにいくつかの有用なデータを持っている場合はどうなりますか?最も簡単な方法は、別の方法で上書きすることですが、どちらを使用するのですか?インポートしている場合はローカルのものが上書きされ、エクスポートしている場合はサーバー上のものが上書きされ、同期する場合は古いものが上書きされます。

ただし、場合によっては、同じユーザーの2つのlocalStorageをマージする必要があります。

新しい要素

要素が新しい場合は、このセッションで作成されたことを何らかの方法で知る必要があります。これは知っておくと役に立ちます。これは、マージしている他のセッションでは、この新しいアイテムが削除されなかったことを意味しますしたがって、追加するのは直感的です。

要素の変更

2つのケースで同じ要素が異なる場合は、新しいバージョンが優先されます。

削除された要素

興味深いケースは、あるセッションで削除され、別のセッションで更新された場合です。この場合、新しい変更が優先されると思います。


ただし、最善を尽くしても、ユーザーが(およびソフトウェアも)混乱する可能性があるため、サーバー上の各セッションをバックアップすることは理にかなっています。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.