[HTML5] Web Storage

Posted in 모바일/HTML5 // Posted at 2010. 8. 11. 12:46
728x90

클라이언트에 데이터를 저장하다
HTML 5 에는 웹 사이트의 데이터를 클라이언트에 저장할 수 있는 새로운 자료구조인
Web Storage(웹 스토로지) 스펙이 포함되었다

Web Storage 의 개념은 심플하다
'키/ 값' 쌍으로 데이터를 저장하고 키를 기반으로 데이터를 조회하는 패턴이다

그리고 영구저장소(localStorage) 와 임시저장소(sessionStorage)를 따로 두어
데이터의 지속성을 구분할 수 있어 응용 환경에 맞는 선택이 가능하다

Web Storage 는 기존 웹 환경의 쿠키(Cookie)와 매우 유사한 개념이다
사실 거의 차이가 없어 보이기도 하다. 다만 몇 가지 쿠키의 단점를 극복하는 개선점이 도입되었다

그럼 쿠키(Cookie)는?
쿠키는 여전히 유효하고 꽤 적절한 클라이언트 저장도구 이다
HTML 5 에서 Web Storage 스펙을 새로 추가했지만 쿠키를 배제하는 것은 아니다
HTML 5 환경에서도 여전히 쿠키를 이용할 수 있다
다만 어떤 것을 사용할 지는 사용자 선택의 몫이라 하겠다

Web Storage 차이점 (쿠키의 단점?)

- 쿠키는 매번 서버로 전송 된다
웹 사이트에서 쿠키를 설정하면 이후 모든 웹 요청은 쿠키정보를 포함하여 서버로 전송된다
Web Storage 는 저장된 데이터가 클라이언트에 존재할 뿐 서버로 전송은 이루어지지 않는다
이것은 네트워크 트래픽 비용을 줄여 준다는 주요한 장점이 되겠다

- 단순 문자열을 넘어 (스크립트) 객체정보를 저장할 수 있다
문자열 기반 데이터 이외에 체계적으로 구조화된 객체를 저장할 수 있다는 것은 개발 편의성을
제공해 주는 주요한 장점이 된다. 브라우저의 지원 여부를 확인해 봐야 하는 항목이다

- 용량의 제한이 없다
쿠키는 개수와 용량에 있어 제한을 걸어 두고 있다
하나의 사이트에서 저장할 수 있는 최대 쿠키 수는 20 개이다. 그리고 하나의 사이트에서 저장할 수 있는 최대 쿠키 크기는 4KB 로 제한되어 있다. Web Storage 는 이러한 제한이 없다
(그러나 쿠키도 하위키를 이용하면 이러한 제한을 일부 해소할 수 있다.
 그리고 대부분의 시나리오에서 쿠키의 제한으로 까지 데이터를 저장할 일이 없다)

- 영구 데이터 저장이 가능하다
쿠키는 만료일자를 지정하게 되어 있어 언젠가 제거된다.
만료일자로 지정된 날짜에 쿠키는 제거되는 것이다.(만료일자를 지정하지 않으면 세션 쿠키가 된다)

만일 영구 쿠키를 원한다면 만료일자를 굉장히 멀게 설정하여 해결하기도 하였다
(그러나 과연 수 년이 지나도록  쿠키가 유지되어야 할 필요가 있을까?)

WebStorage 는 만료기간의 설정이 없다. 즉 한번 저장한 데이터는 영구적으로 존재하는 것이다
이것이 특별히 장점이 되는지는 잘 모르겠지만 쿠키와의 차이점이라는 것은 분명하다
-----

쿠키와 WebStorage 의 차이점과 개선사항에 대해 알아 보았는데 개인적으로,
Web Storage 가 쿠키보다 훨씬 좋은 이유는 없다고 본다.
다만 한가지 매번 서버로 전송되지 않는다는 특징은 꽤나 유용해 보인다
(특히 경량 환경인 모바일에서는 더욱 더)

그리고 쿠키는 더 상세한 설정이 가능해 어떤 환경에서는 더 적합해 보이기 까지 한다
쿠키에 대한 자세한 내용은 다음의 글을 참고하도록 하자
=> Cookie 제대로 알고 사용하자


로컬 스토로지(localStorage)와 세션 스토로지(SessionStorage)

Web Storgae 는 데이터의 지속성과 관련하여 두 가지 용도의 저장소를 제공한다

우선 기본적으로 Web Storage 는 쿠키와 마찬가지로 사이트의 도메인 단위로 접근이 제한된다
다시말해, A 도메인에서 저장한 데이터는 B 도메인에서 조회할 수 없다는 것이다
이것은 데이터의 보안적 측면에서 당연한 원칙이라 하겠다

- 로컬 스토로지
로컬 스토로지 저장한 데이터를 (명시적으로) 지우지 않는 이상 영구적으로 보관한다
앞서 말한대로, 도메인마다 별도로 로컬 스토로지가 생성된다
windows 전역 객체의 localStorage 라는 컬렉션을 통해 저장/조회가 이루어진다

- 세션 스토로지
세션스토로지는 데이터의 지속성과 액세스 범위에 특수한 제한이 존재한다
세션스토로지는 windows 전역 객체의 sessionStorage 라는 컬렉션을 통해 저장/조회가 이루어진다

데이터 유지 측면:
세션 스토로지는 데이터가 지속적으로 보관되지 않는다
이는 마치 브라우저 기반 세션 쿠키와 그 성질이 비슷한데, 현재 페이지가 브라우징 되고 있는
브라우저 컨텍스트 내에서만 데이터가 유지된다

로컬 스토로지는 브라우저를 종료해도 데이터는 보관되어 다음번 접속에도 그 데이터를
사용할 수 있는 반면, 세션 스토로지는 브라우저가 종료되면 데이터도 같이 지워진다.
브라우저가 종료되면 세션 스토로지도 삭제된다는 것이다

데이터 범위 측면:
세션 스토로지 역시 Web Storage 의 기본 보안 처럼 도메인별로 별도로 생성된다
여기에 더불어 세션 스토로지는 같은 사이트의 같은 도메인이라 할지라도 브라우저가 다르면
서로 다른 영역이 된다(즉 브라우저 컨텍스트가 다르다)

탭 브라우징이나 브라우저를 하나 더 실행해서 같은 페이지를 실행했을 때,
이 두 페이지의 세션 스토로지는 각각 별개의 영역으로 서로 침범하지 못한다는 의미이다
(도메인만 같으면 전역적으로 공유 가능한 로컬스토로지와 구분되는 특징이라 하겠다)


브라우저 지원 현황
아래 표는 http://caniuse.com/ 에서 제공하는 브라우저(버전)별 Web Storage 지원 표이다
(데스크탑 용 브라우저 기준이다)





대부분의 브라우저에서 Web Storage 를 지원하고 있다
특이한 것은 MS의 IE 의 경우 8.0 까지는 대부분의 HTML5 신기능이 지원되지 않는 반면
Web Storage 는 IE 8.0 에서도 지원하는 것으로 나와있다

그리고 아이폰의 사파리에서 테스트를 해 보니 정상적으로 동작하는 것을 확인하였다

다음의 코드로 브라우저 지원 여부를 체크해 볼 수 있다

if( ('localStorage' in window) && window['localStorage'] !== null) {
    alert("현재 브라우저는 WebStorage를 지원합니다")
}
else{
    alert("현재 브라우저는 WebStorage를 지원하지 않습니다")
}


Web Storage 데모 만들어 보기
로컬스토로지와 세션스토로지를 이용하는 간단한 데모를 만들어 보자
<!DOCTYPE html>
<html>
  <head>
    <script type="text/javascript">                     
      //로컬스토로지에 저장               
      function setLocalStorage(){
        var textBox = document.querySelector('#textBox1');
        window.localStorage['key1'] = textBox.value;
      }     
      //로컬스토로지 조회
      function getLocalStorage(){
        var textBox = document.querySelector('#textBox2');
        textBox.value = window.localStorage['key1'];
      }
     
      //세션스토로지에 저장
      function setSessionStorage(){
        var textBox = document.querySelector('#textBox3');
        window.sessionStorage['key1'] = textBox.value;
      }     
      //세션스토로지 조회
      function getSessionStorage(){
        var textBox = document.querySelector('#textBox4');
        textBox.value = window.sessionStorage['key1'];
      }   
    </script> 
  </head>
  <body> 
    <input type="text" id="textBox1">
    <button onclick="setLocalStorage()">로컬스토로지 저장</button>
    <br>   
    <input type="text" id="textBox2">
    <button onclick="getLocalStorage()">로컬스토로지 조회</button>   
    <hr>   
    <input type="text" id="textBox3">
    <button onclick="setSessionStorage()">세션스토로지 저장</button>
    <br>   
    <input type="text" id="textBox4">
    <button onclick="getSessionStorage()">세션스토로지 조회</button>         
  </body>
</html>


아래는 실행화면인데 로컬스토로지와 세션스토로지의 저장소가 각각 분리되어 있는 것을 알 수 있다
그리고 각 스토로지에 Local Files 라고 되어 있는 것은 현재 데모 실행 환경이
로컬 파일 기반인 file//..... 로 되어 있기 때문이다
만일 특정 도메인에서 실행한다면 Local Files 대신 도메인 명이 나타날 것이다

그리고 새로운 탭을 열어서 같은 페이지를 실행 해 보면,
이전 탭 페이지에서 실행한 로컬스토로지 값은 여전히 유효한 반면
 세션스토로지는 서로 공유되지 않고 별도의 저장소를 따로 가진다는 것을 알 수 있다



세션 스토로지와 새창(window.open)
앞서 세션 스토로지는 탭 브라우징이나 새로 실행한 브라우저끼리는 별도의 저장 영역이라 하였다
그렇다면 페이지에서 window.open으로 생성한 새로운 창과 기존 창과의 세션 스토로지 공유는 어떨까?

실제로 어떤 페이지에서 프로그램 논리에 의해 open 하는 창은 물리적으로는 새창이지만,
논리적으로 전혀 별개의 창이라 볼 수 없다.
즉 세션 스토로지 데이터가 이 둘간의 공유가 이루어지는 것이 더 합당해 보인다는 말이다

HTML5 Web Storage 은 이러한 경우 조금 중간적 적인 입장을 취하고 있는 듯 하다
즉 windows.open 으로 띄운 새 창은 새로운 브라우저 컨텍스트로 인식하여
세션스토로지가 따로 생성,관리되지만 최초 데이터는 복사되어 진다는 것이다

다시말해 A 페이지에서 저장한 세션스토로지 값이 새창을 띄울 때 복사되어 전달되고
이후부터는 이 둘의 영역은 전혀 별개의 영역이 된다는 것이다 

결국 세션 스토로지는 각각의 브라우저(윈도우, 창, 실제로는 브라우저 컨텍스트)는 서로 독립된
각각의 세션 스토로지를 가진다는 특징이 있는 것
이다


클라이언트에서는 값을 얼마든지 수정할 수 있다
Web Storage 의 보안은 서로 다른 도메인의 데이터 침범을 막고는 있지만 클라이언트,
즉 사용자를 막고 있지는 않다. 클라이언트는 얼마든지 저장된 값을 (임의로) 수정할 수 있다
이것은 이전 쿠키와 완전 동일한 개념이다

아래 그림은 구글 크롬 브라우저에서 개발자 도구를 실행한 모습인데,
Wb Storage 에 저장된 값을 수정하거나 삭제 할 수 있는 것을 알 수 있다



클라이언트가 저장된 값을 임의로 변경 할 수 있다는 것은 쿠키와 동일한 개념으로 별다른 보안 취약점을 더 가진 것은 아니다. 따라서 웹 사이트 개발자는 사용자에 의한 이러한 임의 변경에 항상 예의 주시하고 방어 코드의 작성을 잊지 말아야 하겠다

다음의 사이트에서 추가 내용과 데모를 확인해 보기 바란다
http://www.ibm.com/developerworks/kr/library/x-html5mobile2/
http://html5demos.com/storage

'모바일 > HTML5' 카테고리의 다른 글

[HTML5] Web SQL Database  (0) 2010.08.17
[HTML5] 오프라인 웹 어플리케이션  (0) 2010.08.12
[HTML5] 드래그 앤 드롭 (Drag & Drop)  (3) 2010.08.10
[HTML5] Geolocation  (1) 2010.08.09
[HTML5] Web Workers (웹 워커)  (1) 2010.08.05