웹에서 리소스를 저장할 수 있는 저장소는 여러 가지가 존재합니다.
우리는 이 모든 저장소를 사용해도 되는걸까요? 아니면 데이터의 종류에 따라 다른 저장소를 사용해야 하는 걸까요?
아래는 유튜브 영상(Storage for the web)의 스크린샷입니다.
왜 LocalStorage
의 사용을 피하라고 하는 것일까요?
아래는 위의 영상에 나오는 분께서 작성하신 글과 localStorage 사용을 중지하라는 블로그 글을 보고 정리한 내용입니다.
그럼 어떤 저장소를 사용해야할까요?
제가 검색한 내용을 토대로 정리해보면 공통적으로 Cache API
, IndexedDB
를 사용하라고 합니다.
그럼 각 저장소에는 어떤 데이터를 저장하는 것이 좋을까요?
Cache API
Indexed DB
하지만, 무조건 Local Storage
를 사용하지 말고 Cache API
와 Indexed DB
를 사용해야 한다는 것은 아닙니다. 간단한 웹사이트를 만든다면 LocalStorage
사용해도 크게 문제가 되지 않을 것이기 때문입니다.
그리고 Cookie
는 HTTP 요청시 함께 보내지기 때문에 인증과 인가에 많이 사용됩니다.
브라우저에 따라 다를 수 있지만 일반적으로 장치에서 사용 가능한 저장 공간의 양에 따라 결정된다고 합니다.
예를 들어, 현재 디스크 공간이 994GB라면, 994GB * 0.6 = 596.4GB를 사용할 수 있다는 것을 의미합니다.
실제로 콘솔에서 quota(byte단위) 값을 출력해보면 596797550592 Byte가 출력되는 것을 알 수 있고 GB로 변환해보면 약 596GB라는 것을 알 수 있습니다.
사용 가능한 할당량을 초과하면 IndexedDB
와 Cache API
모두 QuotaExceededError
라는 DOMError
를 발생시킵니다.
// IndexedDB
const transaction = idb.transaction(['entries'], 'readwrite');
transaction.onabort = function(event) {
const error = event.target.error; // DOMException
if (error.name == 'QuotaExceededError') {
// Fallback code goes here
}
};
// Cache API
try {
const cache = await caches.open('my-cache');
await cache.add(new Request('/sample1.jpg'));
} catch (err) {
if (error.name === 'QuotaExceededError') {
// Fallback code goes here
}
}
에러가 포착되면 처리하는 것이 중요합니다. 예를 들어 오랫동안 액세스하지 않은 콘텐츠를 삭제하거나, 크기를 기준으로 데이터를 제거하거나, 사용자가 삭제할 항목을 선택할 수 있는 방법을 제공할 수 있습니다.
그런데, 브라우저는 quota가 초과하면 자동으로 삭제하는 로직을 가지고 있습니다.
chrome, firefox와 같은 chromium 기반의 브라우저들은 할당량이 초과하면 최근에 가장 적게 사용한 데이터를 자동으로 삭제합니다. (persistent storage - 사용자만 삭제할 수 있는 데이터 제외)
예를 들어, 현재 아래와 같이 용량이 차있다고 해봅시다.
그리고 사용자가 n 사이트에 접속하여 오프라인에서도 음악을 듣기 위해 음악을 저장했더니 저장용량이 초과했습니다.
이 때 브라우저는 persistent storage(b)를 제외하고 최근에 가장 적게 사용한 storage를 삭제합니다.
반면에 safari는 할당량이 초과하면 새로운 데이터를 막습니다. 그리고 7일 동안 데이터를 사용하고 사이트를 이용하지 않으면 사이트의 모든 데이터가 사라집니다.
두 스토리지 객체는 동일한 메서드와 프로퍼티를 가집니다.
session이란?
영어에서 세션이란 어떤 활동이 수행되는 시간 블록을 가리킵니다. 따라서 웹 세션은 사용자가 첫 페이지에 도착하는 순간부터 사이트를 떠날 때까지 웹 사이트를 탐색하는데 걸리는 시간이라고 할 수 있습니다.
(In English, the word "session" refers to a discrete block of time during which an activity is performed. A web session is therefore the amount of time that a user spends browsing a given website: from the moment they arrive on the first page, to the moment they leave the site.)
쿠키는 어떻게 저장될까요? 서버가 HTTP 응답 헤더의 Set-Cookie
에 내용을 넣어 전달하면, 브라우저는 이 내용을 브라우저에 저장합니다.
document.cookie
프로퍼티를 이용하면 브라우저에서도 쿠키에 접근하거나 직접 값을 저장할 수 있습니다.
document.cookie
는 name=value
쌍으로 구성되어 있고, 각 쌍은 ;
으로 구분합니다. 이 때, 쌍 하나는 하나의 독립된 쿠키를 의미합니다.
따라서, ;
을 기준으로 document.cookie
를 분리하면 원하는 쿠키를 찾을 수 있습니다.
document.cookie
에 값을 할당하면 브라우저는 해당 쿠키를 업데이트하는데 다른 쿠키의 값은 변경되지 않습니다.
옵션은 key=value
뒤에 나열하고 ;
로 구분합니다.
document.cookie = "user=Choi; path=/; expires=Tue, 19 Jan 2038 03:14:07 GMT"
이 경로나 이 경로의 하위 경로에 있는 페이지만 쿠키에 접근할 수 있습니다.
// 모든 페이지에서 접근 가능하도록 하기
document.cookie = "user=Choi; path=/;
쿠키에 접근 가능한 domain을 지정합니다. 아무 값도 넣지 않으면 쿠키를 설정한 도메인에서만 쿠키에 접근 가능합니다.
expires나 max-age 옵션이 지정되어있지 않으면, 브라우저가 닫힐 때 쿠키도 함께 사라집니다.
따라서, expires
나 max-age
옵션을 설정하면 브라우저를 닫아도 쿠키가 삭제되지 않습니다.
expires
는 반드시 GMT(Greenwich Mean Time) 포맷으로 설정해야 합니다. date.toUTCString
을 사용하면 해당 포맷으로 쉽게 변경할 수 있습니다.
// 유효기간이 하루인 쿠키
let date = new Date(Date.now() + 86400000);
date = date.toUTCString(); // 'Fri, 08 Apr 2022 02:11:53 GMT'
document.cookie = "user=Choi; expires=" + date;
max-age
는 expires
의 대안으로 좀 더 쉽게 유효기간을 설정할 수 있게 해줍니다.
// 유효기간이 하루인 쿠키
document.cookie = "user=Choi; max-age=86400";
secure 옵션을 설정하면 HTTPS
로 통신하는 경우에만 쿠키가 전송됩니다.
따라서, https://site.com
에서 설정한 쿠키는 http://site.com
에서 접근할 수 없습니다.
// https:// 로 통신하고 있다고 가정
document.cookie = "user=Choi; secure";
httpOnly
옵션은 서버에서 Set-Cookie
헤더를 이용해 쿠키를 설정할 때 지정할 수 있습니다. httpOnly
옵션을 설정하면 document.cookie
를 통해 쿠키에 읽거나 쓸 수 없습니다.
https://developer.mozilla.org/ko/docs/Web/HTTP/Cookies
https://developer.mozilla.org/ko/docs/Web/API/Web_Storage_API
https://codepen.io/beaucarnes/pen/KmeRMx
https://ko.javascript.info/localstorage
https://ko.javascript.info/cookie
https://web.dev/i18n/ko/storage-for-the-web
https://blog.sessionstack.com/how-javascript-works-storage-engines-how-to-choose-the-proper-storage-api-da50879ef576
https://www.rdegges.com/2018/please-stop-using-local-storage
https://www.youtube.com/watch?v=NNuTV-gjlZQ&t=496s