Rev. 2.73

HTML 5에 명시된 'localStorage'는 클라이언트 로컬에 데이터를 저장하기 위한 전역 함수입니다. 여기에 저장된 데이터는 장시간 영구적으로 보관할 수 있으며, 오프라인인 경우에도 호출이 가능하다는 특징 때문에 Ajax 응답 결과물 또는 무리한 연산 결과물 등을 캐싱하거나 오프라인 환경을 고려한 데이터베이스 동기화 등 웹 애플리케이션의 성능 향상을 꾀하기 위한 목적으로 사용될 수 있습니다. 부가적으로 서버측 로드는 줄고 트래픽이 절감하는 효과도 발생합니다. 그래서 아래와 같은 스토리지 도우미를 작성했습니다.

/* Local Storage Helper Class */
var Storage = Class.create({
  initialize: function(name, options) {
    this.options = Object.extend({
      clearable: true, // automatically clear data if an error occurred
      delay: 2000, // save data to localStorage after the allotted time
      maximum: 5 // the maximum size in megabytes
    }, options);

    if (typeof localStorage == "undefined" && typeof globalStorage != "undefined")
      window.localStorage = globalStorage[location.hostname];
      this.localStorage = window.localStorage;
    // undefined localStorage if it doesn't already exist
    if (!this.localStorage) this.localStorage = {
        getItem: function(name) {
          this.data = window.name ? window.name.evalJSON() : {};
          return $H(this.data[name] || (this.data[name] = {})).toJSON();
        }, setItem: function(name, data) {
          this.data[name] = data.evalJSON();
          window.name = $H(this.data).toJSON();
        }, removeItem: function(name) {
          delete this.data[name];
          window.name = $H(this.data).toJSON();
        }
      };

    this.name = name || 'unnamed';
    this.data = this.get();
  },
  // get item from localStorage
  get: function() {
    try {
      return (this.localStorage.getItem(this.name) || '{}').toString().evalJSON();
    } catch(e) {
      this.options.clearable && this.set({});
    }
  },
  // set item to localStorage
  set: function(data) {
    if (data) this.data = data;
    this.timer && clearTimeout(this.timer);
    this.timer = setTimeout(function() {
      if (this.size(true) > this.options.maximum * 1048576) return;
      try {
        this.localStorage.setItem(this.name, $H(this.data).toJSON());
      } catch(e) {
        this.options.clearable && this.set({});
      }
    }.bind(this), this.options.delay)
  },
  // remove item
  remove: function(name) {
    this.localStorage.removeItem(name || this.name);
  },
  // remove all items
  clear: function() {
    if (!this.localStorage.length)
      window.name = '{}';
    else
      for (i = 0; i < this.localStorage.length; i++) this.remove(this.localStorage.key(i));
  },
  // size of localStorage
  size: function(bytes) {
    var data = $H(this.data).toJSON().length;
    return bytes ? data : data > 1024 ? (function() {
      data = (data / 1024).round().toString();
      var reg = /(^[+-]?\d+)(\d{3})/;
      while (reg.test(data)) data = data.replace(reg, '$1' + ',' + '$2');
      return data  + 'kb';
    })() : data + 'bytes';
  }
});

/* Usage */
var MyStorage = new Storage('MyStorage'); // Create the helper instance
var MyData = MyStorage.data; // Read data from localStorage(JSON Object)
MyData['firejune'] = { name: 'Junho, Kyung', age: 33 }; // Update a single data
MyStorage.set(MyData); // Write the data to localStorage
MyStorage.size(); // => '49bytes'

위 코드는 이 블로그의 이미지 프로세싱 결과동적인 자바스크립트 호출 결과에 실제로 반영되어 사용되고 있습니다. JSON 자료형으로 입/출력하며, JSON을 문자로 변환 보관하기 위해 json2.js 라이브러리를 필요로 합니다.(브라우저가 Native JSON을 지원하지 않는 경우)합니다. localStorage를 사용할 수 없는 브라우저인 경우에는 단기적으로 자료 보존이 가능한 'window.name' 프로퍼티에 저장하는 트릭을 사용합니다. 그리고 불필요한(비효율적인, 반복적인) 저장 호출들을 무시하기 위해 타이머(기본 2초)가 적용되어 있으며 옵션으로 타이머 시간값을 변경할 수 있습니다. 신기하게도 'localStorage.setItem'메서드로 자료가 입력되는 동시에 하드디스크를 '드르륵' 긁더라구요.

덧1. 문득 떠오른 뻘아이디어: 이렇게 모인 캐시들을 cometd를 이용해서 접속중인 모든 클라이언트에 전송하고 머지해 버리면 어떤 현상이 발생할까요? 이름하여 '미러링 캐시 이펙트'? ㅎㅎㅎ
덧2. 도메인당 최대 자료 저장량이 브라우저에 따라 다르므로 초기화가 자동으로 이루어질 수 있도록 옵션으로 제공 함(Firefox의 최대 저장량 5 MB)
덧3. window.name을 스토리지로 사용하는 경우에도 인스턴스 단위로 구분하여 저장 함
덧4. 해당 인스턴스의 스토리지 사용량을 반환하는 size() 메서드 추가
덧5. window.name을 스토리지로 사용하는 경우 지속적으로 초기화 되던 버그 수정
덧6. 인스턴스당 최대 저장량을 설정할 수 있도록 함(자동으로 초기화하지 않음)
덧7. 구글 크롬에서 발생하는 "localStorage is null" 오류 수정

Comments

Got something to add? You can just leave a comment.

  • 우노 우노

    저의 경우에는 localstorage가 online 에 있는 html 파일의 경우에는 동작을 하는데, local 에 있는 html 파일에서는 동작하지 않습니다. 원래 안되는 것인지요? 아니면 특별히 지정해야 하는 환경설정이 있는 것인지요?

    reply edit

  • 도메인당 스토리지 공간을 할당하도록 설계되어서 그런걸 겁니다.

    reply edit

  • 박우영 박우영

    localstorage 에 바이너리 정보는 넣을 수가 없나요? 예를 들면 비디오/오디오 정보같은거요..

    reply edit

Your Reaction Time!

captcha

avatar