노트

localStorage와 sessionStorage

Web Storage API

프론트엔드#browser#js · 연결된 개념 8개

쉽게 말하면

localStorage는 브라우저에 둔 개인 사물함이라 탭을 닫아도 남고, sessionStorage는 탭마다 받는 임시 바구니라 탭을 닫으면 비워져요. 서버에 묻지 않고도 설정이나 장바구니를 기억할 수 있죠.

비유의 한계 사물함이지만 잠금장치는 없어요. 같은 출처의 모든 스크립트가 읽을 수 있어 XSS에 노출돼요. 쿠키와 달리 요청에 자동으로 안 실리고, 문자열만 담는 동기 API라 큰 데이터는 IndexedDB를 써요.

브라우저에 문자열 키-값을 저장하는 Web Storage API의 두 가지. 쿠키와 달리 요청에 자동으로 실리지 않고, 출처 단위로 나뉘며(동일 출처 정책), 보통 출처당 5MB 안팎을 쓸 수 있다. 동기 API라 큰 데이터를 자주 읽고 쓰면 메인 스레드를 막는다.

동작localStoragesessionStorage
새로고침유지유지
같은 탭에서 같은 출처 페이지 이동유지유지
같은 사이트를 새 탭으로 열기공유탭마다 따로
탭 복제공유그 시점 값을 복사해 따로
탭 닫기유지삭제
브라우저 재시작유지보통 삭제(세션 복원 기능이 살리기도 함)

새로고침했는데 sessionStorage 값이 사라진다면 저장소 특성이 아니라 코드 어딘가가 초기화하고 있을 가능성이 크다.

storage 이벤트로 탭 간 동기화

같은 출처의 다른 탭에서 localStorage가 바뀌면 storage 이벤트가 온다. 값을 바꾼 탭 자신에게는 오지 않는다. 이벤트에는 key, oldValue, newValue, url, storageArea가 담긴다.

// 로그아웃한 탭: 신호를 남긴다
localStorage.setItem('logout', Date.now().toString())
 
// 나머지 탭: 신호를 받으면 함께 로그아웃
addEventListener('storage', e => {
  if (e.key === 'logout') location.href = '/'
})

서버 없이 로그인 상태, 장바구니, 설정을 여러 탭에 맞출 수 있다. React에서 이런 외부 저장소를 구독할 때는 useSyncExternalStore가 맞는 도구다.

주의

  • 같은 출처의 모든 스크립트가 읽을 수 있으므로 XSS(Cross-Site Scripting)에 노출된다. 토큰을 여기 두면 CSRF(Cross-Site Request Forgery) 위험은 줄지만 XSS 위험을 떠안는다 → JWT
  • 문자열만 저장하므로 객체는 JSON.stringify로 바꾼다
  • 큰 데이터나 구조화된 데이터는 비동기 API인 IndexedDB를 쓴다
  • 앱 안 웹뷰의 Web Storage는 앱의 네이티브 저장소와 자동으로 공유되지 않는다 → 모바일 네이티브 저장소

출처: MDN — Web Storage API · MDN — Window: storage event

연결된 개념

이 노트를 가리키는 문서

뜻이 가까운 노트

  • 무상태와 상태 유지

    무상태(stateless)는 서버가 이전 요청을 기억하지 않아도 요청 하나만 보고 처리할 수 있는 구조이고, 상태 유지(stateful)는 서버가 요청 사이에 클라이언트 상태를 저장해 두고 다음 요청을 처리할 때 그 상태를 찾아보는 구조다.

  • 구조적 공유

    구조적 공유(Structural Sharing)는 새 버전의 데이터를 만들 때 바뀌지 않은 부분은 이전 버전의 객체를 그대로 가리키게 하는 기법이다. 바뀐 노드와 그 노드까지 올라가는 경로만 새로 만들고, 나머지 가지는 두 버전이 함께 쓴다. 불변 데이터를 다루면서도 매번 전체를 복사하지 않게 해 준다.

  • 세션 인증

    서버가 로그인 상태를 저장하고, 브라우저는 세션 id(session identifier)만 쿠키로 들고 다니는 방식. 서버에서 세션을 지우면 즉시 로그아웃되고, 세션 쿠키에 HttpOnly를 붙이면 스크립트로 읽을 수 없다.

  • 브라우저 캐시

    한 번 받은 리소스(HTML·CSS·JS·이미지)를 브라우저가 저장해 두었다가 다시 쓰는 기능. 서버가 응답 헤더로 얼마나, 어떻게 캐시할지 알려 주고 브라우저가 그대로 따른다.

  • 롱 태스크

    메인 스레드를 50ms 넘게 붙잡는 작업. W3C Long Tasks 명세는 이벤트 루프 태스크(뒤따르는 마이크로태스크 처리 포함), 렌더링 갱신 단계, 이벤트 루프 밖에서 브라우저가 UI 스레드로 하는 일 가운데 50ms를 넘는 것을 롱 태스크로 본다. 태스크는 도중에 끊기지 않으므로 그동안 클릭·키 입력 처리와 화면 갱신이 모두 밀린다(이벤트 루프).

보기 옵션