쿠키
4KB의 저장 용량, 크기가 작다.
같은 사이트내에서 둘 이상의 탭을 열었을 때, 둘 이상의 트랜젝션 추적에 어려움이 있다.
이 외에도 여러 보안문제가 있다.
웹 스토리지
사양에 따르면 크기 제한이 없다.
서버로 보내지 않는다.(원하면 명시적으로 보낼 수 있다.)
유효기간이 없다.
JavaScript 객체를 저장할 수 있다.(정확하게는 객체의 복사본이 저장된다.)
웹 스토리지에는 Session Storage와 Local Storage가 있다.
Listing 1. 가장 기본적인 Twitter 검색
Listing 2. 검색 및 저장하기
그림 1. 로컬로 캐시된 트윗
Listing 3. 로컬로 먼저 검색하기
Listing 4. 상위 10개의 검색 계산하기
Listing 5. 페이지 초기화하기
Listing 6. 스토리지 이벤트 처리기
Session Storage
- 도메인마다 따로 생성된다.
- 윈도우(window 객체)와 같은 유효범위와 생존기간을 가진다. (같은 도메인이라도 윈도우마다 따로 생성된다.)
- 윈도우 복제로 생성된 경우, 스크립트를 이용해 새 창을 연 경우 같은 값을 가진 세션 스토리지가 "복제"된다.
- 새로 생성된 윈도우와 기존 윈도우의 세션 스토리지는 서로 영향을 주지 않는다.
Local Storage
- 도메인마다 따로 생성된다.
- 지속기간에 제한이 없다. 사용자가 명시적으로 지우지 않는 한 영구적으로 저장된다.
- 도메인이 다르면 서로의 로컬 스토리지에 접근할 수 없다. (hi.croute.me와 hello.croute.me는 다른 로컬 스토리지)
- 같은 도메인, 예를들면 croute.me에 소속된 웹페이지는 모두 같은 로컬 스토리지를 가진다.(접근한다.)
- Cookie를 이용한 사이트 고유 설정 정보등을 대신하기에 적당하다.
세션과 로컬의 차이점은 로컬은 지속성(보존)을 가지기 때문에 여러 창을 켜도 같은 도메인이라면, 같은 스토리지를 사용하는 것입니다.
세션 스토리지는 각 세션마다 새로운 스토리지를 사용하고 폐기합니다.메소드 | 설명 |
length | 스토리지에 저장된 데이터의 수를 반환 |
key(index) | 지정된 인덱스의 키를 반환하고 키가 없다면 null 반환 |
getItem(key) | 지정된 키에 대응하는 데이터를 반환 |
setItem(key, data) | 지정된 키로 스토리지에 데이터를 저장 |
removeItem(key) | 지정된 키에 대응하는 데이터를 삭제 |
clear() | 모든 데이터를 스토리지에서 삭제 |
// 저장
localStorage.croute = "good job";
localStorage["croute"] = "good job";
localStorage.setItem("croute", "good job");
// 읽기
var croute = localStorage.croute;
var croute = localStorage["croute"];
var croute = localStorage.getItem["croute"];
// 삭제
delete localStorage.croute;
delete localStorage["croute"];
localStorage.removeItem("croute");
localStorage.setItem('name', 'arman'); localStorage.removeItem('name'); var value = localStorage.getItem('name'); alert(value);
for(var i = 0; i < localStorage.length; i++)
{
var key = localStorage.key(i);
var value = localStorage[key];
}
- localStorage.clear();
- localStorage.setItem("title", "Mr.");
- localStorage.setItem("fullname", "Aaron Darwin");
- localStorage.setItem("age", 17);
- localStorage.setItem("height", 182.5);
- for(var i = 0; i < localStorage.length; i++)
- {
- var keyName = localStorage.key(i);
- var value = localStorage.getItem(keyName);
- alert(keyName + " = " + value);
- }
- var imageObject = new Image("http://www.google.com/logo.gif");
- localStorage.setItem("image", imageObject);
- var integerVariable = 34;
- localStorage.setItem("age", integerVariable);
- var newVariable = localStorage.getItem("age");
- alert(typeof(newVariable) == "number");
- var integerVariable = 34;
- localStorage.setItem("age", integerVariable);
- var newVariable = parseInt(localStorage.getItem("age"));
- alert(typeof(newVariable) == "number");
- if (window.addEventListener) {
- window.addEventListener("storage", handleStorageChange, false);
- }
- else
- {
- window.attachEvent("onstorage", handleStorageChange);
- }
- function handleStorageChange(event)
- {
- alert("Something was changed in the local storage");
- }
- interface StorageEvent : Event {
- readonly String <strong>key</strong>;
- readonly Object <strong>oldValue</strong>;
- readonly object <strong>newValue</strong>;
- readonly String <strong>url</strong>;
- };
- <!DOCTYPE html>
- <html>
- <head>
- <meta name="viewport" content="width=240,user-scalable=no" />
- <style>
- * { padding: 0px; margin: 0px; font-family: "Lucida Sans", "Tahoma", san-serif, arial; }
- body { background: #333; }
- h1 { font-size: 20px; }
- p { padding: 5px; margin-bottom: 10px; font-size: 12px; }
- button { padding: 4px; margin-top: 10px; }
- #wrap { width: 240px; background: #FFF; margin: 0px auto; padding: 10px; }
- #blocks .unchecked, a { height: 40px; width: 40px; margin: 4px; display: inline-block; cursor: pointer; text-align: center; line-height: 40px; }
- #blocks .unchecked { background: #000; }
- #blocks .unchecked:hover { background: #333; }
- </style>
- <script>
- var colorTable = {
- "0" : "blue",
- "1" : "red",
- "2" : "green",
- "3" : "orange",
- "4" : "purple",
- "5" : "brown",
- "6" : "gold",
- "7" : "lime",
- "8" : "lightblue",
- "9" : "yellow"
- };
- function initializeGame()
- {
- if (browserSupportsLocalStorage() == false)
- {
- alert("This browser doesn't support Web Storage standard");
- return;
- }
- var containerDiv = document.getElementById("blocks");
- for (var i = 0; i < 10; i++)
- {
- var iid = i.toString();
- var anchor = document.createElement("a");
- anchor.id = id;
- anchor.innerHTML = i + 1;
- if (localStorage.getItem(id) != null)
- {
- anchor.style.backgroundColor = colorTable[id];
- }
- else
- {
- anchor.className = "unchecked";
- if (anchor.addEventListener)
- {
- anchor.addEventListener("click", handleBoxClick, false);
- }
- else
- {
- anchor.attachEvent("onclick", handleBoxClick);
- }
- }
- containerDiv.appendChild(anchor);
- }
- }
- function handleBoxClick(e)
- {
- var target = (e.target) ? e.target : e.srcElement;
- if (target.className == "")
- return;
- var id = target.id;
- var color = colorTable[id]
- target.className = "";
- target.style.backgroundColor = colorTable[id];
- localStorage.setItem(id, color);
- }
- function resetGame()
- {
- var containerDiv = document.getElementById("blocks");
- containerDiv.innerHTML = "";
- localStorage.clear();
- initializeGame();
- }
- function browserSupportsLocalStorage()
- {
- return ('localStorage' in window) && (window['localStorage'] != null);
- }
- </script>
- </head>
- <body onload="initializeGame();">
- <div id="wrap">
- <h1>Web Storage Demo</h1>
- <p>
- This page was design to simply demonstrate the use of Web Storage in modern browsers. In this example boxes
- that haven't yet been clicked remain black. Once you click a black box, it's real color will be revealed.
- The browser however will remember which boxes are clicked, even when you navigate away from this page.
- Go on, give it a try.
- </p>
- <div id="blocks">
- </div>
- <button onclick="resetGame()">Reset Game</button>
- <button onclick="document.location.reload(true);">Refresh Page</button>
- </div>
- </body>
- </html>
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta name = "viewport" content = "width = device-width"/> <title>Basic Twitter Search</title> <script type="text/javascript"> function searchTwitter(){ var query = "http://search.twitter.com/search.json?callback =showResults&q="; query += $("kwBox").value; var script = document.createElement("script"); script.src = query; document.getElementsByTagName("head")[0].appendChild(script); } // ui code deleted for brevity function showResults(response){ var tweets = response.results; tweets.forEach(function(tweet){ tweet.linkUrl = "http://twitter.com/" + tweet.from_user + "/status/" + tweet.id; }); makeResultsTable(tweets); } </script> <!-- CSS deleted for brevity --> </head> <body> <div id="main"> <label for="kwBox">Search Twitter:</label> <input type="text" id="kwBox"/> <input type="button" value="Go!" onclick="searchTwitter()"/> </div> <div id="results"> </div> </body> </html> |
function searchTwitter(){ var keyword = $("kwBox").value; var query = "http://search.twitter.com/search.json?callback =processResults&q="; query += keyword; var script = document.createElement("script"); script.src = query; document.getElementsByTagName("head")[0].appendChild(script); } function processResults(response){ var keyword = $("kwBox").value; var tweets = response.results; tweets.forEach(function(tweet){ saveTweet(keyword, tweet); tweet.linkUrl = "http://twitter.com/" + tweet.from_user + "/status/" + tweet.id; }); makeResultsTable(); addTweetsToResultsTable(tweets); } function saveTweet(keyword, tweet){ // check if the browser supports localStorage if (!window.localStorage){ return; } if (!localStorage.getItem("tweet" + tweet.id)){ localStorage.setItem("tweet" + tweet.id, JSON.stringify(tweet)); } var index = localStorage.getItem("index::" + keyword); if (index){ index = JSON.parse(index); } else { index = []; } if (!index.contains(tweet.id)){ index.push(tweet.id); localStorage.setItem("index::"+keyword, JSON.stringify(index)); } } |
Listing 3. 로컬로 먼저 검색하기
function searchTwitter(){ if ($("resultsTable")){ $("resultsTable").innerHTML = ""; // clear results } makeResultsTable(); var keyword = $("kwBox").value; var maxId = loadLocal(keyword); var query = "http://search.twitter.com/search.json?callback=processResults&q="; query += keyword; if (maxId){ query += "&since_id=" + maxId; } var script = document.createElement("script"); script.src = query; document.getElementsByTagName("head")[0].appendChild(script); } function loadLocal(keyword){ if (!window.localStorage){ return; } var index = localStorage.getItem("index::" + keyword); var tweets = []; var i = 0; var tweet = {}; if (index){ index = JSON.parse(index); for (i=0;i<index.length;i++){ tweet = localStorage.getItem("tweet"+index[i]); if (tweet){ tweet = JSON.parse(tweet); tweets.push(tweet); } } } if (tweets.length < 1){ return 0; } tweets.sort(function(a,b){ return a.id > b.id; }); addTweetsToResultsTable(tweets); return tweets[0].id; } |
function displayStats(){ if (!window.localStorage){ return; } var i = 0; var key = ""; var index = []; var cachedSearches = []; for (i=0;i<localStorage.length;i++){ key = localStorage.key(i); if (key.indexOf("index::") == 0){ index = JSON.parse(localStorage.getItem(key)); cachedSearches.push ({keyword: key.slice(7), numResults: index.length}); } } cachedSearches.sort(function(a,b){ if (a.numResults == b.numResults){ if (a.keyword.toLowerCase() < b.keyword.toLowerCase()){ return -1; } else if (a.keyword.toLowerCase() > b.keyword.toLowerCase()){ return 1; } return 0; } return b.numResults - a.numResults; }).slice(0,10).forEach(function(search){ var li = document.createElement("li"); var txt = document.createTextNode(search.keyword + " : " + search.numResults); li.appendChild(txt); $("stats").appendChild(li); }); } |
window.onload = function() { displayStats(); document.body.setAttribute("onstorage", "handleOnStorage();"); } |
function handleOnStorage() { if (window.event && window.event.key.indexOf("index::") == 0){ $("stats").innerHTML = ""; displayStats(); } } |
'HTML & Script' 카테고리의 다른 글
urlencode (0) | 2012.02.01 |
---|---|
input 박스에 숫자만 입력 (1) | 2011.12.02 |
encodeURI (0) | 2011.09.27 |
jQuery 폼유효성검사 간단히 (0) | 2011.09.26 |
[html5]The Root Element (0) | 2011.06.02 |