DB없이 장치 전체에서 localStorage를 확장하는 방법


10

목표 :localStorage 앱에서 이미 구현 한 것을 로컬이 아닌 것으로 확장 합니다.


로컬 저장소 API를 사용하여 간단한 사용자 설정을 저장하는 것을 좋아합니다. 나는 웹 응용 프로그램에서 내 요구에 맞게 작동하지만 유일한 문제는 사용 / 저장되는 해당 컴퓨터 / 브라우저의 로컬 문제입니다. 이에 대한 고전적인 MySQL 스타일 테이블에 액세스 할 수 없습니다. 로컬 브라우저를 확장하거나 다른 브라우저로 옮기고 싶습니다. 또는 사용자 JS 객체 및 JS 객체 속성에 내 사용자 설정을 저장하십시오.

  • 나는 새로운 사용자가있을 때마다 이름을 가져와 객체를 만들거나 object[key]이름을 가지고 필드 속성 기본 변수를 처음에 변수가 채워지거나 각 사용자마다 JSON 또는 JavaScript 객체를 만드는 아이디어를 좋아합니다. 사용자가 저장하면 재정의됩니다.
  • 또는 위의 내용이 찌그러진 경우; 로컬 스토리지 구현이 잘 작동하면서 플러그인 / 라이브러리 / 확장 프로그램 을 찾아서 저장하고 다른 위치에 다시 렌더링 할 수 있도록하고 싶습니다. 이것은 이전에 생각되었습니다. 클라이언트 쪽을 유지하고 싶지만; 나는 파이썬 솔루션뿐만 아니라 node.js 솔루션에 개방되어 있으며 간단한 데이터 프레임이 충분히 작동해야합니다.
  • localStorage데이터 로 파일을 생성하는 것은 어떻습니까? 아마도 .csv 파일 (이것은 중요하지 않은 데이터입니다) 내 파일 처럼 업데이트 localStorage됩니까?

2
이 클라이언트 측만 수행 할 수 없습니다. 여러 브라우저에서 사용자 정보를 유지하려면 공용 서버가 필요하며 정보를 저장해야합니다. 일반적으로 이것은 데이터베이스를 사용하여 수행됩니다. mySQL을 사용하지 않으려면 다른 유형의 데이터 스토리지가 있습니다. Firebase는 여러분이 상상 한 것과 매우 유사하며 임의의 구조의 객체를 저장할 수 있습니다. (또한 JSON은 텍스트 형식입니다. JSON 객체와 같은 것은 없습니다)
Chris G

다소 비슷합니다 : stackoverflow.com/a/60279503/4845566 ?
블로커

답변:


3

sqlite를 사용하는 것은 어떻습니까?

서버에 csv와 같은 하나의 파일 만 있습니다. http 요청 보내기 클라이언트 측에서 로컬 저장소를 업데이트 한 후 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) / 클라우드 스토리지 (AWS S3)

수출:

사용자 ID별로 값을 업데이트 할 때 엔드 포인트에 대한 HTTP POST.

수입:

사용자 ID 별 엔드 포인트의 HTTP GET


추가 : PouchDB

동기화되는 데이터베이스!

PouchDB는 Apache CouchDB에서 영감을 얻은 오픈 소스 JavaScript 데이터베이스 이며 브라우저에서 잘 실행되도록 설계되었습니다.

PouchDB는 웹 개발자가 온라인과 마찬가지로 오프라인에서도 작동하는 응용 프로그램을 구축 할 수 있도록하기 위해 만들어졌습니다. 응용 프로그램은 오프라인 상태에서 로컬로 데이터를 저장 한 다음 응용 프로그램이 온라인 상태 일 때 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에서 디코딩> 팽창> json 구문 분석

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

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

URL 매개 변수는 꽤 길지만 최대 10 배 적습니다.


이! 그러나 로컬 스토리지 데이터를 콘솔 로그하면 ~ 20k 및 ~ 8k 문자입니다. 여전히 이런 식으로 할 수 있습니까?
문서 휴일

1
160k 문자로 테스트했습니다. 수축 후 1600 자입니다 .IE조차도 문제없이 작동합니다 (예 : 최대 URL 길이-2048). 최신 브라우저는 URL 길이에 제한이 없습니다.
Anton Chukanov

감사! pako는 도서관이나 무언가가 필요합니까? pako undefined
doc holiday

1
"현대 브라우저는 URL 길이에 제한이 없습니다"는 잘못된 가정 입니다. 내용을 참조하십시오 . 또한 pako는 여기에서 찾을 수있는 JavaScript 라이브러리입니다 ( GitHub , cdnjs ). 마지막으로, 압축률은 데이터 내용에 따라 달라질 수 있습니다.
DK Dhilip

2

로컬 저장소를 사용하는 대신 사용자의 설정을 IPFS (InterPlanetary File System) https://ipfs.io/에 저장하십시오.

기본적으로 JSON과 같은 데이터 형식을 설정 한 다음 파일에 쓰고 IPFS로 푸시합니다.

어떤 데이터가 어떤 사용자에게 전달되는지 식별하는 방법이 필요합니다. 아마도 사용자 이름과 비밀번호의 해시를 사용하여 파일 이름이나 이와 유사한 이름을 지정할 수 있습니다. 그러면 사용자는 비밀번호를 잊어 버리지 않는 한 항상 모든 장치에서 콘텐츠에 액세스 할 수 있습니다.


1

보다 복잡한 데이터 구조 (배열, 객체)를 저장할 수 있고 스타일 콜백, 약속 및을 지원한다는 점 localForagelocalStorage제외하고 는 기본적으로 API와 동일한 API 인 라이브러리를 사용할 수 있습니다 .nodejsasync await

다음은 예제 사용법을 찾을 수 있는 저장소 링크 와 프로젝트에서 원하는 방식으로 구현하는 방법입니다.


깔끔하게 보입니다. 하지만 같은 외모는 보통 로컬 스토리지로 DB에 동일한 제한이 있습니다
문서 휴일

1

데이터를 공유하기 위해 데이터베이스를 사용하지 않고 이것을 구현하는 가장 좋은 방법은 WebRTC 솔루션 기반이라고 생각합니다.이를 수행하는 방법으로 생각했지만 (적어도 지금은) 코드가 없습니다. 일부 검색 나는 누군가가 이미 (정확하지는 않지만 약간의 조정으로 준비가되어 있음) 여기있고 신호 서버가없는 이 기사 webrtc 의 일부를 발견했습니다.

여기에 하나 이상의 소스가 있습니다 : 데이터 채널 기본 예제 데모

그리고 github에서 : 데이터 채널 기본 예

WebRTC는 화상 / 음성 채팅뿐만 아니라 문자 메시지 및 공동 작업에서 문자 편집에도 사용할 수 있습니다.

이 솔루션은 여기 에 대한 답변 중 하나에서 언급되었습니다 .


0

쿠키를 사용하거나 사용자가 다른 브라우저에 액세스 할 때 쿠키와 함께로드 할 수있는 다운로드 가능한 파일이 있어야합니다. 객체 데이터가있는 텍스트, JSON 또는 JavaScript 파일을 사용하여이 작업을 수행 할 수 있습니다.


쿠키도 로컬에만 있다고 생각합니까?
문서 휴일

여러 웹 사이트에서 동일한 "소스"를 사용하는 경우 타사 쿠키를 사용할 수 있습니다.

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

데이터베이스 없이이 문제를 해결할 수는 있지만 권장하지는 않습니다. 기본적으로 당신은 (사용자, localStorage) 쌍을 가지고 있으며 주어진 사용자가 자신을 식별 할 때, 그 / 그녀의 localStorage는 방식으로 제공되어야합니다. 사용자에게 로컬 저장소를 자신의 컴퓨터에 저장하라고 지시 할 수 있지만 다른 컴퓨터에 복사해야하므로 노동 집약적이며 인기를 얻지 못할 것입니다. 브라우저의 콘솔에서 수동으로 Javascript 청크를 실행하여 localStorage에 데이터가 있는지 확인하고 localStorage 전체 머신을 복사하는 것이 전체 작업을 수동으로 수행하는 것보다 약간 더 쉽습니다.

localStorage 정보를 URL로 인코딩 할 수 있지만 문제가 될 수있는 URL 길이 문제 외에도 현재 인코딩 문제가 발생하면 라우터에 액세스하여 타사에서 전체 localStorage를 모니터링 할 수 있습니다. 데이터가 중요하지 않다고 말했지만 아직 민감 하지 않다고 생각합니다 . 그러나 일단 사용자가 이것을 사용하면 편리하다면 민감한 데이터도 저장하거나 고객이 그러한 작업을 수행하거나 100 % 공개되지 않은 데이터를 저장해야한다는 사실을 깨닫게됩니다.

이 외에도 실제로 동기화의 매우 심각한 문제에 직면하게됩니다. 즉, localStorage를 불가지론 적으로 만드는 것이 좋지만 실제 버전은 무엇입니까? 10 개의 서로 다른 세션에서 정기적으로 작업하는 경우 로컬 저장소 동기화가 어려운 문제가됩니다. 이는 localStorage에 타임 스탬프가 필요하다는 것을 의미합니다.

따라서 마지막으로 저장된 localStorage 버전을 저장하는 서버 인 중앙 위치가 필요합니다. 알 수없는 이유로 데이터베이스를 피할 경우 다음과 같이 사용자를 식별하는 파일 내에 localStorage를 저장할 수 있습니다.

johndoe.json

그런 다음 내보내기 기능을 구현해야합니다.이 기능은 사용자의 현재 JSON을 서버로 전송하고이를 파일 및 가져 오기 기능에 저장하여 사용자를 위해 저장된 파일을 다운로드하고 localStorage가 업데이트되도록합니다. 따라서. 동기화를 구현하여 두 가지를 함께 수행 할 수도 있습니다.

이것은 지금까지 간단하지만 사용자가 이미 로컬 localStorage 및 서버에 유용한 데이터를 가지고 있다면 어떨까요? 가장 간단한 방법은 서로를 재정의하는 것입니다. 가져 오는 경우 로컬 항목이 무시되고, 내보내는 경우 서버의 항목이 재정의되고 동기화하면 이전 항목이 재정의됩니다.

그러나 경우에 따라 동일한 사용자의 두 개의 로컬 저장소를 병합하려고합니다.

새로운 요소

요소가 새로운 것이라면 어떤 방식 으로든이 세션에서 생성되었다는 것을 알아야합니다. 이는 우리가 병합하는 다른 세션에서이 새 항목이 제거되지 않았 음을 의미하기 때문에 유용합니다. 따라서 추가하는 것이 직관적입니다.

요소 변경

두 경우에서 동일한 요소가 다른 경우 최신 버전이 우선합니다.

제거 된 요소

흥미로운 사례는 한 세션에서 제거되고 다른 세션에서는 업데이트 된 경우입니다. 이 경우 새로운 변화가 우선해야한다고 생각합니다.


그러나 최선의 노력에도 불구하고 사용자는 여전히 시스템을 엉망으로 만들 수 있으므로 서버의 각 세션을 백업하는 것이 좋습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.