HTML5 : Client-Side Storage
http://www.html5rocks.com/tutorials/offline/storage/HTML5 offers two new objects for storing data on the client:
* localStorage - stores data with no time limit
* sessionStorage - stores data for one session
: 초기에 웹 애플리켕이션에서는 데이터저장을 서버측 데이터베이스나 브라우저 쿠키가
담당했지만, HTML5의 등장으로 웹 개발자들은 더 많은 선택의 여지가 생겼는데 그것은
localStorage, sessionStorage, client-side databases.
localstorage와 sessionStorage는 다수의 페이지들을 검색할 때 name/value 쌍을 설정하기
위해 javascript를 사용한다는 점에서 쿠키와 매우 유사하다. 하지만, 쿠키와 달리 부라우저이 요청이 있을 때 데이터를 와이어를 통해 전송하지 않는데, 데이터는 오직 클라이언트에만 존재한다. 그러므로 쿠키보다 더 많은 데이터를 저장하는 것이 가능하다.
이 둘은 기능적으로는 같지만, 지속성과 범위 측면에서만 다르다.
localStorage
- 윈도우가 닫힌 후에도 데이터가 저장된다. 데이터는 같은 소스(도메인네임,프로토콜,
포트가 같아야 한다.)로부터 로드된 모든 윈도우에서 사용 가능하다.
이는 애플리케이션 환경설정 같은 것에 유용하다.
sessionStorage
- 데이터는 윈도우객체와 함께 저장된다. 다른 윈도우(or Tab)들은 데이터 값을 알지
못하고 윈도우가 닫힐때 사라진다. 활성화된 탭을 강조하는 것과 같은 윈도우의 특정
상태만을 저장할 때나 테이블 정렬 순서를 저장할 때 유용하다.
value 설정 : localStorage.setItem('age', 35);
저장된 value 호출 : var age = localStorage.getItem('age');
특정한 key/value 삭제하기 : localStorage.removeItem(age);
모든 key/value 삭제하기 : localStorage.clear();
ex) kilo.js
var db;
var jQT = $.jQTouch({
icon: 'kilo.png',
statusBar: 'black'
});
$(document).ready(function() {
$('#createEntry form').submit(createEntry);
$('#settings form').submit(saveSettings);
// jQTouch 덕분에 pageAnimationStart 이벤트에 loadSetting()함수를 바인딩하는것은 간단하다.
$('#settings').bind('pageAnimationStart', loadSettings);
$('#dates li a').click(function(){
// 클릭된 객체의 id를 가로채서 dayoffset 변수에 저장.
var dayOffset = this.id;
var date = new Date();
date.setDate(date.getDate() - dayOffset);
// sessionStorage 에 currentDate로 저장한다.
sessionStorage.currentDate = date.getMonth() + 1 + '/' + date.getDate() + '/' + date.getFullYear();
refreshEntries();
});
//shortName : 디스크에 있는 database를 호출하기 위해 몇 개의 var을 정의하고 있다.
var shortName = 'Kilo';
// version : Database 스키마를 바꿀 필요가 있을 경우,
// 업그레이드와 이전 버전과의 호환을 처리하기 위해 사용한다.
var version = '1.0';
// displayName : 사용자 인터페이스에 보이는 문자열
// 예를 들어 아이폰에 있는 Setting 애플레케이션에서
// Setting > Safari > Database panel 에 displayName이 보인다.
var displayName = 'Kilo';
//Database 가 가지는 최대 크기를 킬로바이트 단위로 지정한다.
var maxSize = 65536;
//위 설정된 파라미터를 가지고 openDatabase 함수를 호출하고 연결을 db변수에 저장한다.
// 만약 Open 하고자 하는 database가 존재하지 않으면 새로 생성한다.
db = openDatabase(shortName, version, displayName, maxSize);
// transaction 메서드를 호출.
db.transaction(
//익명 함수를 사용하여 파라미터로 트랜잭션을 전달한다.
function(transaction) {
// 함수 내부에서 표준 CREATE TABLE 쿼리를 실행하기 위해
// 트랜잭션 객체의 excuteSql메서드를 호출한다.
transaction.executeSql(
'CREATE TABLE IF NOT EXISTS entries ' +
' (id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, ' +
' date DATE NOT NULL, food TEXT NOT NULL, ' +
' calories INTEGER NOT NULL );'
);
}
);
});
function saveSettings() {
localStorage.age = $('#age').val();
localStorage.budget = $('#budget').val();
localStorage.weight = $('#weight').val();
jQT.goBack();
return false;
}
function loadSettings() {
$('#age').val(localStorage.age);
$('#budget').val(localStorage.budget);
$('#weight').val(localStorage.weight);
}
function refreshEntries() {
var currentDate = sessionStorage.currentDate;
$('#date h1').text(currentDate);
$('#date ul li:gt(0)').remove();
db.transaction(
function(transaction) {
transaction.executeSql(
'SELECT * FROM entries WHERE date = ? ORDER BY food;',
[currentDate],
function (transaction, result) {
for (var i=0; i < result.rows.length; i++) {
var row = result.rows.item(i);
var newEntryRow = $('#entryTemplate').clone();
newEntryRow.removeAttr('id');
newEntryRow.removeAttr('style');
newEntryRow.data('entryId', row.id);
newEntryRow.appendTo('#date ul');
newEntryRow.find('.label').text(row.food);
newEntryRow.find('.calories').text(row.calories);
newEntryRow.find('.delete').click(function(){
var clickedEntry = $(this).parent();
var clickedEntryId = clickedEntry.data('entryId');
deleteEntryById(clickedEntryId);
clickedEntry.slideUp();
});
}
},
errorHandler
);
}
);
}
function createEntry() {
// SQL에 사용할 변수를 설정한다.
var date = sessionStorage.currentDate;
var calories = $('#calories').val();
var food = $('#food').val();
db.transaction(
function(transaction) {
transaction.executeSql(
// ?는 플래이스 홀더(자리표시)이다.
'INSERT INTO entries (date, calories, food) VALUES (?, ?, ?);',
// Database에 전송될 값들의 배열.
// place holder에 대응되는 값이다.
[date, calories, food],
// 이 익명함수는 SQL쿼리가 성공하면 실행된다.
function(){
refreshEntries();
jQT.goBack();
},
// SQL 쿼리가 실패하면 실행될 함수 이름이다.
errorHandler
);
}
);
return false;
}
// Entry 삽입이 실패하면 실행.
// 에러 핸들러는 두개의 파라미터가 전송된다. 트랜잭션 객체와 에러 객체이다.
// error 핸들러는 true 나 false 를 반환한다.
// 에러핸들러가 true를 반환할 때는 실행이 멈추고 전체 트랜잭션이 RollBack 한다.
// " false를 반환할 때는 계속 실행.
// ERROR Code
// Constant Code Situation
// UNKNOWN_ERR 0 트랜잭션실패.Database자체와는 무관하고, 다른 오류코드에 포함되지 않는다.
// DATABASE_ERR 1 Statement 실패
// VERSION_ERR 2 Operation 실패. 버전이 다르다.
// TOO_LARGE_ERR 3 Statement 실패. DB에서 리턴된 데이터가 너무 크다.SQL LIMIT modifier권유
// QUOTA_ERR 4 Statement 실패. 남아있는 공간이 충분하지 않거나 저장공간 할당량 초과.
// SYNTAX_ERR 5 Statement 실패. Syntax 에러,파라미터의 수가 맞지 않거나, 허용되지 않는 문자열 시도
// CONSTRAINT_ERR 6 Constraint 실패로 인해 insert, update, replace statement 실패
// TIMEOUT_ERR 7 Transaction을 위한 lock이 주어진 시간을 초과하였다.
function errorHandler(transaction, error) {
alert('Oops. Error was '+error.message+' (Code '+error.code+')');
return true;
}
function deleteEntryById(id) {
db.transaction(
function (transaction) {
transaction.executeSql('DELETE FROM entries WHERE id=?;', [id], null, errorHandler);
}
);
}
Posted by 홍반장