Cách mở rộng localStorage trên các thiết bị (không có DB)


10

Mục tiêu: mở rộng đã được triển khai localStoragetrong ứng dụng của tôi, để tốt, không phải địa phương tôi đoán.


Tôi thích việc thực hiện lưu cài đặt người dùng đơn giản với API lưu trữ cục bộ. Tôi có điều này hoạt động cho nhu cầu của mình trong một ứng dụng web, nhưng vấn đề duy nhất là nó cục bộ với máy / trình duyệt đó đang được sử dụng / lưu. Tôi không có quyền truy cập vào bảng kiểu MySQL cổ điển cho việc này. Tôi muốn mở rộng hoặc điều chỉnh bộ nhớ cục bộ của mình để chuyển sang các trình duyệt khác; hoặc lưu trữ cài đặt người dùng của tôi trong các đối tượng JS người dùng và thuộc tính đối tượng JS.

  • Tôi thích ý tưởng chỉ tạo các đối tượng JSON hoặc JavaScript với mỗi người dùng, bất cứ khi nào có người dùng mới, lấy tên, tạo đối tượng hoặc object[key]với tên và có các biến mặc định thuộc tính trường lúc đầu và các biến trở nên phổ biến và ghi đè khi người dùng lưu chúng.
  • Hoặc nếu những điều trên được nhăn mặt; muốn duy trì triển khai lưu trữ cục bộ của tôi vì nó hoạt động rất tốt và tìm một plugin / thư viện / tiện ích mở rộng nào đó cho phép tôi cũng lưu phần này và kết xuất lại ở các vị trí khác nhau; điều này đã được nghĩ đến trước đây. Mặc dù tôi rất thích giữ nó bên khách hàng; Tôi đang mở cho một giải pháp node.js cũng như giải pháp python, một khung dữ liệu đơn giản của các loại sẽ hoạt động đủ.
  • Điều gì về việc tạo một tập tin với localStoragedữ liệu của tôi ? Có lẽ một tệp .csv (đây là dữ liệu không nhạy cảm) và có cập nhật như của tôi localStoragekhông?

2
Bạn không thể làm điều này chỉ phía khách hàng. Để duy trì thông tin người dùng trên các trình duyệt, bạn cần một máy chủ công cộng và lưu trữ thông tin trên đó. Thông thường, điều này được thực hiện bằng cách sử dụng cơ sở dữ liệu; nếu bạn không muốn sử dụng myQuery, có các loại lưu trữ dữ liệu khác. Firebase khá gần với những gì bạn tưởng tượng, nó cho phép bạn lưu trữ các đối tượng có cấu trúc tùy ý. (ngoài ra, JSON là một định dạng văn bản. Không có thứ gọi là đối tượng JSON)
Chris G

hơi giống với điều đó: stackoverflow.com/a/60279503/4845566 ?
gỡ lỗi

Câu trả lời:


3

Còn việc sử dụng sqlite thì sao?

Chỉ cần một tệp trên máy chủ của bạn như csv. Gửi một yêu cầu http Để cập nhật nó bằng cách sử dụng câu lệnh SQL bằng knex hoặc một cái gì đó tương tự sau khi cập nhật bộ lưu trữ cục bộ ở phía máy khách.

Ít nhất nó tốt hơn cvs tôi nghĩ bởi vì bạn có thể định nghĩa một vài bảng, có khả năng mở rộng hơn và hiệu quả hơn, bạn biết đấy, đó là một cơ sở dữ liệu.


2

Tôi đang thêm hai xu của tôi ở đây.


Xuất / Nhập tệp (JSON, XML, CSV, TSV, v.v.)

Xuất khẩu:

Nối tiếp cài đặt và tải xuống dưới dạng tệp.

Nhập khẩu:

Mở tệp cài đặt nối tiếp được xuất / tải xuống.

Mã ví dụ:

<!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 (Chuỗi truy vấn)

Xuất khẩu:

Mã hóa cài đặt thành chuỗi truy vấn và kết hợp với URL hiện tại dưới dạng siêu liên kết.

Nhập khẩu:

Truy cập vào siêu liên kết có chứa chuỗi truy vấn với cài đặt được mã hóa, sau đó JavaScript phát hiện và tải cài đặt từ chuỗi truy vấn.


Dữ liệu được mã hóa Base64

Xuất khẩu:

Nối tiếp các cài đặt sau đó mã hóa nó thành chuỗi Base64, sau đó sao chép vào clipboard.

Nhập khẩu:

Dán chuỗi Base64 từ bảng ghi tạm vào hộp văn bản để giải mã, giải nén và tải các cài đặt.


Mã QR

Xuất khẩu:

Mã hóa cài đặt thành chuỗi truy vấn và kết hợp với URL hiện tại dưới dạng siêu liên kết. Sau đó tạo ra một hình ảnh mã QR và hiển thị.

Nhập khẩu:

Quét hình ảnh mã QR được tạo và tự động truy cập vào siêu liên kết.


Máy chủ HTTP (Node.js) / Lưu trữ đám mây (AWS S3)

Xuất khẩu:

POST HTTP tự động đến điểm cuối khi cập nhật giá trị, theo id người dùng.

Nhập khẩu:

HTTP GET từ điểm cuối bởi id người dùng.


Thêm: PouchDB

Cơ sở dữ liệu đồng bộ hóa!

PouchDB là một cơ sở dữ liệu JavaScript mã nguồn mở được lấy cảm hứng từ Apache CouchDB , được thiết kế để chạy tốt trong trình duyệt.

PouchDB được tạo ra để giúp các nhà phát triển web xây dựng các ứng dụng hoạt động ngoại tuyến cũng như trực tuyến. Nó cho phép các ứng dụng lưu trữ dữ liệu cục bộ trong khi ngoại tuyến, sau đó đồng bộ hóa nó với CouchDB và các máy chủ tương thích khi ứng dụng trực tuyến trở lại, giữ cho dữ liệu của người dùng được đồng bộ hóa bất kể họ đăng nhập lần sau ở đâu.


Cảm ơn vì sự trả lời. Tốt nhất chưa; với lần nhập / xuất đầu tiên - tôi có thể làm cho nó để người dùng có thể chỉ cần mở tệp để cài đặt tải? Làm thế nào mà có thể làm việc?
doc ngày

1
Đã thêm mã ví dụ để xuất / nhập tệp JSON.
DK Dhilip

Ah tôi thấy. Cảm ơn bạn. Tôi chỉ nghĩ rằng đó là một chút để hỏi từ người dùng. Nếu có một cách tôi có thể tạo một siêu liên kết và gửi email cho họ có lẽ. Tôi nghĩ rằng dữ liệu của tôi chứa quá nhiều ký tự để đặt trong chuỗi truy vấn URL. Làm thế nào để tùy chọn mã QR được quét?
doc ngày

Nếu dữ liệu của bạn quá lớn để phù hợp với chuỗi truy vấn, có lẽ bạn có thể thử nghiệm với gzip / deflate cộng với Base64 để xem liệu nó có thể giảm kích thước tải trọng và bao gồm trong chuỗi truy vấn không? Tôi không biết nếu điều này sẽ làm việc đủ tốt cho trường hợp của bạn, chỉ là một suy nghĩ ngẫu nhiên. Đối với tùy chọn mã QR, nó có thể được quét bởi bất kỳ thiết bị nào có máy ảnh hoặc quét tệp hình ảnh trực tiếp (từ URL thông thường, URL dữ liệu, tệp mở).
DK Dhilip

Để mở rộng ý tưởng giảm kích thước dữ liệu, bạn cũng có thể thử tuần tự hóa dữ liệu của mình thành ArrayBuffer để làm cho nó nhỏ nhất có thể và sau đó áp dụng mã hóa Base64 cho nó tùy thuộc vào phương thức truyền tải.
DK Dhilip

2

Bạn có thể sử dụng URL làm bộ lưu trữ nếu bạn nén các thông số người dùng của mình.
lấy thông số bạn muốn lưu trữ> json> deflate> mã hóa thành base64> đẩy vào URL

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

onload: lấy thông số từ url> giải mã từ base64> thổi phồng> parse json

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

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

Thông số url sẽ khá dài, nhưng ít hơn 10 lần thì khả dụng tối đa


Điều này! Tuy nhiên, khi tôi điều khiển đăng nhập dữ liệu lưu trữ cục bộ của mình, nó là ~ 20k và ~ 8k ký tự. Tôi vẫn có thể làm một cái gì đó như thế này?
doc ngày

1
Tôi đã thử nghiệm với 160k ký tự. Nó sẽ là 1600 ký tự sau khi giảm phát, thậm chí IE sẽ hoạt động mà không gặp vấn đề gì (độ dài url tối đa tức là - 2048). Các trình duyệt hiện đại không có giới hạn về độ dài url.
Anton Chukanov

Cảm ơn! pako có cần một thư viện hay cái gì không? Tôi đang nhận được pako không xác định
ngày lễ doc

1
"Các trình duyệt hiện đại không có giới hạn về độ dài URL" là một giả định sai, vui lòng tham khảo điều này . Ngoài ra, pako là một thư viện JavaScript có thể tìm thấy ở đây ( GitHub , cdnjs ). Cuối cùng, xin lưu ý rằng tỷ lệ nén có thể thay đổi tùy theo nội dung dữ liệu.
DK Dhilip

2

Thay vì sử dụng bộ lưu trữ cục bộ, hãy lưu trữ cài đặt của người dùng của bạn trong Hệ thống tệp liên ngân hàng (IPFS) https://ipfs.io/

Về cơ bản, bạn sẽ đặt cài đặt của chúng là định dạng dữ liệu như JSON và sau đó ghi nó vào tệp và đẩy nó sang IPFS.

Bạn sẽ cần một cách để xác định dữ liệu nào sẽ được chuyển đến người dùng nào. Có lẽ bạn có thể sử dụng hàm băm của tên người dùng và mật khẩu để đặt tên cho tệp của mình hoặc đại loại như thế. Sau đó, người dùng của bạn sẽ luôn có thể truy cập nội dung của họ trên bất kỳ thiết bị nào (miễn là họ không quên mật khẩu).


1

Bạn có thể sử dụng một thư viện được gọi localForagelà về cơ bản có cùng API, localStoragengoại trừ nó cho phép bạn lưu trữ các cấu trúc dữ liệu phức tạp hơn (mảng, đối tượng) và cũng hỗ trợ nodejsgọi lại kiểu, lời hứa và async await.

Đây là một liên kết đến kho lưu trữ nơi bạn có thể tìm thấy các cách sử dụng ví dụ và cách triển khai nó trong dự án của bạn theo cách bạn muốn.


Cảm ơn mà trông gọn gàng; nhưng có vẻ như nó có cùng giới hạn với DB như localStorage bình thường
ngày lễ doc ngày

1

Cách tốt nhất để thực hiện điều này mà không cần sử dụng cơ sở dữ liệu để chia sẻ dữ liệu, tôi tin rằng đó là giải pháp WebRTC , tôi nghĩ đó là một cách để làm điều đó nhưng tôi không có mã cho nó (ít nhất là bây giờ), vì vậy với Một số tìm kiếm tôi đã tìm thấy ai đó đã làm nó (không chính xác, nhưng với một số điều chỉnh, nó sẽ sẵn sàng) ở đây , ví dụ, và một phần của bài viết này webrtc mà không cần máy chủ báo hiệu

đây là một nguồn nữa: bản demo ví dụ cơ bản về kênh dữ liệu

và trên github: ví dụ cơ bản về kênh dữ liệu

WebRTC không chỉ để trò chuyện video / âm thanh, nó còn có thể được sử dụng trong nhắn tin văn bản và cộng tác trong chỉnh sửa văn bản.

Giải pháp này thậm chí được đề cập trong một trong những câu trả lời ở đây .


0

Sử dụng cookie hoặc có tệp có thể tải xuống mà người dùng có thể mang theo để tải khi họ truy cập trình duyệt khác. Bạn có thể làm điều này với một tệp văn bản, JSON hoặc JavaScript với dữ liệu đối tượng.


Tôi tin rằng cookie chỉ là địa phương là tốt?
doc ngày

Cookie của bên thứ ba có thể được sử dụng bởi nhiều trang web nếu chúng dựa trên cùng một "nguồn".

0

Bạn có thể sử dụng Redis . Nó là một kho lưu trữ cấu trúc dữ liệu trong bộ nhớ, được sử dụng làm cơ sở dữ liệu. Bạn có thể lưu trữ dữ liệu của bạn trong các định dạng cặp chính. Nó cũng làm cho ứng dụng của bạn nhanh chóng và hiệu quả.


0

Rõ ràng cách tiếp cận tốt nhất là sử dụng cơ sở dữ liệu. Tuy nhiên, nếu bạn có xu hướng sử dụng cơ sở dữ liệu thì cách tiếp cận tốt nhất có thể là sử dụng kết hợp các kỹ thuật mà tôi tin rằng bạn đã chạm vào để tôi sẽ giúp bạn kết nối các dấu chấm ở đây.

Các bước cần thiết:

  1. API LocalStorage (Vì nó đã hoạt động một phần cho bạn).
  2. Xây dựng một Node hoặc Python (Hoặc những gì bạn cảm thấy thoải mái) để kết nối dữ liệu cài đặt GET và POST.
  3. Tạo một tệp userSinstall.JSON trên máy chủ API của bạn.

Hướng dẫn:

Bạn sẽ sử dụng localStorage giống như cách bạn đang sử dụng bây giờ (trạng thái làm việc hiện tại).

Để di chuyển hoặc có cài đặt người dùng trên các thiết bị khác nhau, tệp userSinstall.JSON (đóng vai trò là cơ sở dữ liệu tài liệu) sẽ được sử dụng để lưu trữ và nhập cài đặt người dùng.

Điểm cuối API của bạn sẽ được sử dụng để NHẬN cài đặt người dùng nếu không tồn tại trong localStorage. Khi cập nhật cài đặt, hãy cập nhật localStorage của bạn và sau đó POST / CẬP NHẬT các cài đặt mới trong tệp userSinstall.JSON bằng cách sử dụng điểm cuối của bạn.

Điểm cuối API của bạn sẽ chỉ được sử dụng để duy trì (đọc và ghi) tệp userSinstall.JSON. Bạn sẽ cần một phương thức / chức năng để tạo, cập nhật và có thể xóa các cài đặt trong tệp của bạn. Như bạn có thể đã biết, định dạng tệp JSON không khác nhiều so với cơ sở dữ liệu MongoDB. Trong trường hợp này, bạn chỉ đang tạo các phương thức bạn cần để quản lý tệp của mình.

Tôi hi vọng cái này giúp được!


-1

Bạn có thể giải quyết vấn đề này mà không cần cơ sở dữ liệu, nhưng tôi không khuyến nghị. Về cơ bản, bạn có các cặp (người dùng, localStorage) và khi một người dùng nhất định tự nhận mình, localStorage của anh ấy / cô ấy nên được cung cấp theo cách. Bạn có thể yêu cầu người dùng lưu trữ kho lưu trữ cục bộ của họ tại máy riêng của họ, nhưng sau đó họ sẽ phải sao chép nó sang các máy khác, sử dụng nhiều lao động và sẽ không bao giờ phổ biến. Người ta có thể tự chạy một đoạn Javascript trong bảng điều khiển của trình duyệt của họ để đảm bảo rằng localStorage có dữ liệu của họ và phải sao chép các máy cục bộ cục bộ chỉ dễ dàng hơn một chút so với thực hiện thủ công toàn bộ.

Bạn có thể đặt thông tin localStorage được mã hóa vào một URL, nhưng bên cạnh vấn đề về độ dài URL, có thể trở thành vấn đề và hiện tại vấn đề mã hóa, toàn bộ localStorage của bạn có thể được giám sát bởi bên thứ ba, có quyền truy cập vào bộ định tuyến của bạn. Tôi biết bạn đã nói rằng các dữ liệu không phải là nhạy cảm, nhưng tôi tin rằng bạn biết rằng nó không bị ảnh hưởng chưa . Nhưng một khi người dùng sẽ sử dụng điều này, nếu thuận tiện, họ cũng sẽ lưu trữ dữ liệu nhạy cảm hoặc khách hàng của bạn có thể có những nhiệm vụ đó cho bạn hoặc thậm chí bạn có thể nhận ra rằng bạn cần lưu trữ dữ liệu không công khai 100%.

Bên cạnh đó, trong thực tế, bạn sẽ phải đối mặt với các vấn đề đồng bộ hóa rất nghiêm trọng, đó là tất cả đều tốt đẹp để biến bất khả tri của LocalStorage, nhưng sau đó, phiên bản thực sự là gì? Nếu bạn thường xuyên làm việc trên 10 phiên khác nhau, thì việc đồng bộ hóa LocalStorages trở thành một vấn đề khó khăn. Điều này có nghĩa là localStorage cần được đánh dấu thời gian.

Vì vậy, bạn sẽ cần một vị trí trung tâm, một máy chủ để lưu trữ phiên bản localStorage đã lưu cuối cùng. Nếu bạn bị đảo ngược bởi cơ sở dữ liệu vì một số lý do không rõ ràng, bạn có thể lưu trữ LocalStorages bên trong các tệp xác định người dùng, như

johndoe.json

và sau đó, bạn sẽ cần triển khai một tính năng xuất, sẽ gửi JSON hiện tại của người dùng đến máy chủ và lưu nó vào một tệp và một tính năng nhập, sẽ tải xuống tệp được lưu trữ cho người dùng và đảm bảo rằng localStorage được cập nhật phù hợp. Bạn có thể làm cả hai cùng nhau, thực hiện đồng bộ hóa.

Điều này là đơn giản cho đến nay, nhưng nếu người dùng đã có một số dữ liệu hữu ích bên trong localStorage cục bộ của mình và trên máy chủ thì sao? Cách tiếp cận đơn giản nhất là ghi đè cái này với cái khác, nhưng cái nào? Nếu chúng ta đang nhập, thì cái cục bộ bị ghi đè, nếu xuất, thì cái trên máy chủ bị ghi đè, nếu chúng ta đồng bộ hóa, thì cái cũ hơn sẽ bị ghi đè.

Tuy nhiên, trong một số trường hợp, bạn muốn hợp nhất hai LocalStorages của cùng một người dùng, vì vậy:

yếu tố mới

Tôi tin rằng nếu một yếu tố là mới, thì nó phải được biết theo một cách nào đó rằng nó đã được tạo trong phiên này, điều này rất hữu ích để biết, bởi vì điều đó có nghĩa là trong phiên khác mà chúng tôi đang hợp nhất, mục mới này đã không bị xóa và do đó trực quan để thêm nó.

thay đổi yếu tố

Nếu cùng một yếu tố khác nhau trong hai trường hợp, thì phiên bản mới hơn sẽ chiếm ưu thế.

loại bỏ các yếu tố

Trường hợp thú vị là khi trong một phiên nó đã bị xóa và trong phiên khác nó đã được cập nhật. Trong trường hợp này tôi nghĩ rằng sự thay đổi mới hơn sẽ chiếm ưu thế.


Tuy nhiên, bất chấp những nỗ lực tốt nhất của bạn, người dùng vẫn có thể làm hỏng (và cả phần mềm của bạn), vì vậy sao lưu mỗi phiên trên máy chủ của bạn có ý nghĩa.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.