본문 바로가기

Front End/Javascript

[JavaScript] localforage 사용해 보기

브라우저에서 데이터를 저장하는 방법에는 여러가지가 존재 합니다. 쿠키, 웹 storage,  indexedDB 등을 이용하는 방법입니다.

사용자의 컴퓨터에 구조화된 방식으로 데이터를 저장할 수 있는 Web SQL Database API (내부적으로는 SQLite 데이터베이스 엔진을 기반으로 함)는 2009년 4월에 도입되었으며 2010년 11월에 폐기되었습니다. 

하지만 웹 storage는 문자열만 처리되고 느리며 Blob(대형 이진 객체, Binary Large Object)를 처리할 수 없습니다. 또한 indexedDB와 WebSQL은 그 API가 복잡하여 배워 사용하기가 쉽지 않습니다. 그리고 모든 브라우져가 지원하지도 않습니다. 그래서 모질라 에서는 로컬포리지(localForage)라 부르는 라이브러리를 만들어 어떤 브라우저에서든지 데이터를 오프라인에 저장하는 일을 훨씬 더 수월하게 처리 할 수 있게 되었습니다.

로컬포리지(localForage)는 localstorage기능에 추가적으로 콜백을 포함한 비동기 API를 지원하고 웹 storage,  indexedDB, WebSQL 등을 자동으로 최상의 드라이버로 읽어서 사용합니다. 또한 Blob 및 ES6의 Promise도 지원 합니다.

 

http://hacks.mozilla.or.kr/2014/05/localforage-offline-storage-improved-2/

 

로컬포리지: 개선된, 오프라인 저장공간 ★ Mozilla 웹 기술 블로그

웹앱은 거대한 데이터세트와 바이너리 파일을 한동안 저장하는 것과 같은 오프라인 기능을 갖고 있습니다. 여러분은 MP3 파일 캐시같은 방식도 쓸 수 있습니다. 브라우저 기술은 데이터를 오프

hacks.mozilla.or.kr

 

 

https://github.com/localForage/localForage/releases

이곳에서 다운로드해서 사용하실 수 있습니다.

 

Releases · localForage/localForage

💾 Offline storage, improved. Wraps IndexedDB, WebSQL, or localStorage using a simple but powerful API. - localForage/localForage

github.com

 

다운로드를 받은 후 압축을 해제하고 html파일에 추가합니다. CDN을 사용하셔도 됩니다.

 

localstorage와 localforage를 이용하여 객체 1개를 저장하고 읽어 보았습니다.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>localforage</title>
    <script>
        // localStorage 사용
        localStorage.clear();
        let user ={id: 1004, name:"한사람",gender : true};
        localStorage.user1 = JSON.stringify(user);
        let user1 = JSON.parse(localStorage.user1);
        console.log(`읽은 값 : ${JSON.stringify(user1)}`);
       
        // localforage 사용
        localforage.ready(()=>{
            localforage.setItem('user2', user, function(){
                console.log(`매개변수들 : ${JSON.stringify(arguments)}`);
                localforage.getItem('user2', (status, data)=>{
                    console.log(`읽은값 : ${JSON.stringify(data)}`)
                });
            });
        });
       
    </script>
</head>
<body>
   
</body>
</html>

 

 

저장소 확인

 

localforge저장소는 크롬이 indexedDB를 지원하므로 자동으로 indexedDB에 저장되었습니다. 드라이버를 지정하지 않으면 알아서 최적의 저장소를 선택해서 저장을 합니다.

 

        // localforage 사용
        // 준비하고
        localforage.ready(()=>{
              // 저장하고
              localforage.setItem(
'user2', user, function(){
                // 읽고
                localforage.getItem('user2', (status, data)=>{
                    // 읽은 값 처리 (첫번쨰 매개변수는 상태값이고 두번째 매개변수가 읽은 데이터값입니다.)
                });
            });
        });

 

 

callback과 Promise를 지원하므로 다음과 같이 사용해도 됩니다.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>localforage</title>
    <script>
        let user ={id: 1004, name:"한사람",gender : true};

        // callback 사용
        localforage.ready(()=>{
            console.log(`1-1. 준비`);
            localforage.setItem('user1', user, function(){
                console.log(`1-2. 저장`);
                localforage.getItem('user1', (status, data)=>{
                    console.log(`1-3. 읽기`);
                    console.log(`읽은값 : ${JSON.stringify(data)}`)
                    localforage.removeItem('user2', ()=>{
                        console.log('1-4. 삭제!!!');
                    });
                });
            });
        });
       
        // Promise 사용
        localforage.ready()
        .then(()=>{
            console.log('2-1. 준비!!!');
            localforage.setItem('user2', user, function(){
                console.log('2-2. 저장!!!');
            });
        })
        .then(()=>{
            localforage.getItem('user2', (status, data)=>{
                console.log('2-3. 읽기!!!');
                console.log(`읽은값 : ${JSON.stringify(data)}`)
            });
        })
        .then(()=>{
            localforage.removeItem('user2', ()=>{
                console.log('2-4. 삭제!!!');
            })
        });
    </script>
</head>
<body>
   
</body>
</html>

 

 

 

배열도 저장이 됩니다. 자동으로 객체의 자료형이 유지가 됩니다.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>localforage</title>
    <script>
        let users = [
            {id: 1004, name:"한사람",gender : true},
            {id: 1005, name:"두사람",gender : false},
            {id: 1006, name:"세사람",gender : false},
        ];
        // 배열의 저장
        localforage.ready()
        .then(()=>{
            localforage.setItem('users', users, function(){
            });
        });

        localforage.ready(()=>{
            localforage.getItem('users', (status, data)=>{
                data.forEach(user => {
                    console.log(`${user.name}(${user.id}, ${user.gender ? "남자":"여자"})`);
                });
            });
        });
    </script>
</head>
<body>
   
</body>
</html>

 

 

Blob을 저장해 보자 이미지를 저장하고 읽어서 화면에 표시해 보겠습니다.

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>localforage</title>
    <script>
        window.onload = () => {
            // 이미지 저장
            localforage.ready(function () {
                fetch('./image1.png')
                    .then((response) => {
                        console.log(response);
                        if(response.status!=200){
                            throw Error('실패!!!');
                        }
                        return response.blob();
                    })
                    .then((blob) => {
                        localforage.setItem('photo', blob, function () {
                            localforage.getItem('photo', function(status, data) {
                                console.log('읽은이미지 : ', data);
                                const img = document.querySelector("#img");
                                let url = URL.createObjectURL(data);
                                img.src = url
                                console.log(url);
                            });
                        });
                    }).catch((error)=>{
                        console.log('에러 발생 : ' + error);
                    });
            });
        }
    </script>
</head>

<body>
    <img src="" id="img" />
</body>

</html>

 

fetch()를 이용하여 이미지를 읽어 blob 형태로 가공하여 localforage의 setItem()을 이용하여 저장했습니다.

 

 localforage의 setItem()을 이용하여 Blob데이터를 읽고 URL.createObject()로 URL을 받아 img태그에 적용시킵니다.

 

 

 

Driver지정하기

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>localforage</title>
    <script>
        window.onload = () => {

            let user = { id: 1004, name: "한사람", gender: true };

            localforage
                .ready()
                .then(function () {
                    localforage.setItem('myuser1', user, function () {
                        console.log('localforage.driver():', localforage.driver());
                        console.log(`저장완료 1`);
                    });
                });

            localforage
                .setDriver(localforage.LOCALSTORAGE)
                .then(function () {
                    localforage.setItem('myuser2', user, function () {
                        console.log('localforage.driver():', localforage.driver());
                        console.log(`저장완료 2`);
                    });
                });
           
            localforage
                .setDriver(localforage.INDEXEDDB)
                .then(function () {
                    localforage.setItem('myuser3', user, function () {
                        console.log('localforage.driver():', localforage.driver());
                        console.log(`저장완료 3`);
                    });
                });

            localforage
                .ready()
                .then(function () {
                    localforage.setItem('myuser4', user, function () {
                        console.log('localforage.driver():', localforage.driver());
                        console.log(`저장완료 4`);
                    });
                }, localforage.LOCALSTORAGE);

            localforage
                .ready()
                .then(function () {
                    localforage.setItem('myuser5', user, function () {
                        console.log('localforage.driver():', localforage.driver());
                        console.log(`저장완료 5`);
                    });
                }, localforage.INDEXEDDB);


            localforage
            .ready()                
            .then(()=>{
                localforage.getItem('myuser1', function (error, data) {
                    console.log(`myuser1 : ${JSON.stringify(data)}`);
                });
                localforage.getItem('myuser2', function (error, data) {
                    console.log(`myuser2 : ${JSON.stringify(data)}`);
                });
                localforage.getItem('myuser3', function (error, data) {
                    console.log(`myuser3 : ${JSON.stringify(data)}`);
                });
                localforage.getItem('myuser4', function (error, data) {
                    console.log(`myuser4 : ${JSON.stringify(data)}`);
                });
                localforage.getItem('myuser5', function (error, data) {
                    console.log(`myuser5 : ${JSON.stringify(data)}`);
                });
            })

        }
    </script>
</head>

<body>
    <img src="" id="img" />
</body>

</html>

 

setDriver()를 이용하여 localforage.LOCALSTORAGE, localforage.INDEXEDDB를 지정했지만 모두 localforage.INDEXEDDB에 저장이 됩니다. 내부적으로 자동으로 최상의 드라이버로 읽어서 사용하도록 되어 있나 봅니다. 여러가지 방법으로 처리 해보았으나 "localforage.ready().then()"을 사용하는것이 제일 편리합니다.

 

image1.png
0.00MB
localforageEx01.html
0.00MB
localforageEx02.html
0.00MB
localforageEx03.html
0.00MB
localforageEx04.html
0.00MB
localforageEx05.html
0.00MB