브라우저에서 데이터를 저장하는 방법에는 여러가지가 존재 합니다. 쿠키, 웹 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()"을 사용하는것이 제일 편리합니다.



'Front End > Javascript' 카테고리의 다른 글
| [JavaScript] localStorage를 이용한 CRUD(저장/읽기/수정/삭제) (0) | 2024.11.18 |
|---|---|
| [JavaScript] 웹 스토리지(localStorage, sessionStorage) 사용해 보기 (0) | 2024.11.18 |
| [JavaScript] SPA/MPA & SSR/CSR (5) | 2024.11.12 |
| [JavaScript] Axios 사용해 보기 (4) | 2024.11.08 |
| [JavaScript] Fetch API 사용해보기 (1) | 2024.11.08 |