관련지식
javascript, storage, session storage, polyfill

사용자가 로그인을 하고 로그아웃을 할 때까지만 사용되어야 하는 값은 임시적으로 필요하지만 로그인 중에는 지속성 있게 유지가 될 필요가 있습니다. 아주 오래전엔 그러한 값들을 쿠키로 관리했습니다. 하지만 쿠키는 브라우저 내의 다른탭끼리도 공유가 되므로 동일 사이트에 다른 사용자로 로그인 할 경우 문제가 발생하기 쉬웠습니다. 세션 스토리지는 탭별로 데이터를 관리할 수 있고 탭이 닫혔을때 모든 데이터는 삭제됩니다.

기본 사용법

sessionStorage.setItem(keyName, keyValue) : keyName 에 해당하는 값을 만들거나 수정합니다.
var aValue = sessionStorage.getItem(keyName) : keyName 에 해당하는 값을 리턴합니다. 키가 없을때는 null 을 리턴합니다.
var aKeyName = sessionStorage.key(index) : index 번째의 키 이름을 리턴합니다.
sessionStorage.length : 저장된 데이터의 갯수를 리턴합니다.
sessionStorage.removeItem(keyName) : keyName 에 해당하는 값을 삭제합니다.
sessionStorage.clear() : 모든 데이터를 삭제합니다.

세션 스토리지는 모든 값을 문자로 저장합니다. 아래와 같은 예제가 있습니다.

  1. sessionStorage.setItem("key1", 10);
  2. sessionStorage.setItem("key2", new Date());
  3. var n = sessionStorage.getItem("key1");
  4. console.log(typeof n); //string 출력
  5. var d = sessionStorage.getItem("key2");
  6. console.log(typeof d); //string 출력

세션 스토리지에 숫자와 Date 객체를 저장했지만 변수 n과 d 의 타입은 둘다 string 으로 출력됩니다. setItem() 함수로 값을 저장할때 모든 값은 문자열로 변환됩니다. 따라서 문자열로 변환 불가능한 객체를 저장하려고 할 경우 ‘[object]’ 같은 값으로 저장될 것입니다.

세션 스토리지를 사용 못하는 경우

세션 스토리지는 기본적으로 IE8 이상에선 모두 사용 가능합니다. 그러나 사용자의 브라우저의 설정 때문에 사용하지 못하는 경우가 있습니다. 그럴때 단순히 경고 메시지로 보여주는 방법도 있지만 내부적으로 대체 기능을 제공하는 방법도 있을 것입니다. 기본 사용법에 명시된 6개의 함수와 length 속성을 만들면 됩니다.

setItem()을 통해 데이터를 저장할 공간이 문제인데 window 객체의 name 속성을 이용할 수 있습니다. 원래는 창의 이름을 지정하기 위한 속성이지만 탭별로 생성되는 속성이고 URL이 전환되어도 사용할수 있으므로 매우 요긴합니다. 최종 샘플에는 이를 이용하여 구현하였습니다.

참고 : https://developer.mozilla.org/ko/docs/Web/API/Window/name

정리

샘플 소스는 화면이 없으므로 개발자 도구를 실행하여 콘솔 로그를 통해 확인해야 합니다.

key() 함수를 구현할때 Object.keys() 함수를 사용했는데 이 함수는 IE9 이상에서만 동작합니다. 따라서 만약 IE8 이상을 지원하고 싶을 경우 1) 해당 함수를 구현하지 않던가 2) 구현 방식을 바꿔야 합니다.

일반적으로는 window.sessionStorage 객체가 있으므로 개발한 코드가 실행되지 않습니다. 첫번째 줄을 주석으로 막고 두번째 줄 주석을 풀어야 개발한 코드로 동작 가능합니다.

최종 샘플

  1. window.sStorage = window.sessionStorage || (function() {
  2. // window.sStorage = (function() {
  3. var winObj = opener || window; //opener가 있으면 팝업창으로 열렸으므로 부모 창을 사용
  4. var data = JSON.parse(winObj.top.name || '{}');
  5. var fn = {
  6. length : Object.keys(data).length,
  7. setItem : function(key, value) {
  8. data[key] = value + '';
  9. winObj.top.name = JSON.stringify(data);
  10. fn.length++;
  11. },
  12. getItem : function(key) {
  13. return data[key] || null;
  14. },
  15. key : function(idx) {
  16. return Object.keys(data)[idx] || null; //Object.keys() 는 IE9 이상을 지원하므로 IE8 이하 브라우저 환경에선 수정되어야함
  17. },
  18. removeItem : function(key) {
  19. delete data[key];
  20. winObj.top.name = JSON.stringify(data);
  21. fn.length--;
  22. },
  23. clear : function() {
  24. winObj.top.name = '{}';
  25. fn.length = 0;
  26. }
  27. };
  28. return fn;
  29. })();
  30. sStorage.setItem("key1", 10);
  31. sStorage.setItem("key2", new Date());
  32. console.log(sStorage.getItem("key1"));
  33. console.log(sStorage.getItem("key2"));
  34. sStorage.removeItem('key2');
  35. sStorage.setItem("key3", '새 문자');
  36. console.log(sStorage.length);
  37. console.log(sStorage.key(1));
  38. sStorage.clear();
  39. console.log(sStorage.length);