Cookie -> WEB Storage (client side data ์ ์ฅ (key-value)) ์ฟ ํค์ ๋์ฒด๋ ์๋ ์๋ก์ด ๊ธฐ์
HTTP์ ํน์ง(stateless)
- ํด๋ผ์ด์ธํธ์ ์ปค๋ฅ์ ์ ์๋ฒ์ ํ๋ฒ ์์ฒญ์ ํ๋ฉด ์๋ต์ ์ฃผ๊ณ ๋์ด๋ฒ๋ฆฐ๋ค
- ํด๋ผ์ด์ธํธ๋ ์๋ฒ์ ์ ์์ ๋ง๋ค ์๋ฒ๋ ์๋ก์ด ์ปค๋ฅ์ ์ผ๋ก ์ธ์ํ๋ฏ๋ก ๋์ผ ํด๋ผ์ด์ธํธ์์ ์ ์ํ๋๋ผ๋ ๊ตฌ๋ถํ ์ ์๋ค.
- ๋์ : session(์๋ฒside์ ํด๋ผ์ด์ธํธ์ ๋ณด ์ ์ฅ)
cookie(ํด๋ผ์ด์ธํธ์ ์ํ์ ๋ณด ์ ์ฅ)์ ํ์ฉ
- request ์ cookie ๋ฐ์ดํฐ๋ฅผ ๋ธ๋ผ์ฐ์ ๊ฐ ์์์ ํด๋น ๋๋ฉ์ธ์ responseํ ๋ head์ ๋ถ์ฌ ์๋ฒ๋ก ๋๊ฒจ์ฃผ๋ ํํ
(์๋ฒ๊ฐ ํ์์๋ ์ฟ ํค์ ๋ณด๋ฅผ ๋ชจ๋ ๋๊ฒจ์ฃผ๋ ํํ์)
----------------------------------------------------------------
WEB Storage ๊ตฌํ
----------------------------------------------------------------
01. ์ค์ฅ
<!DOCTYPE html>
<html>
<head>
<meta charset=EUC-KR">
<title>Insert title here</title>
<script>
window.onload = function(){
var removeBtn = document.getElementById("removeBtn");
var addBtn = document.getElementById("addBtn");
removeBtn.addEventListener("click", remove); //removeBtn์ click์ด๋ฒคํธ ๋ฐ์์ removeํจ์ ํธ์ถ
addBtn.addEventListener("click", add); //addBtn์ click์ด๋ฒคํธ ๋ฐ์์ addํจ์ ํธ์ถ
load();
}
// SelectBox ๊ฐฑ์
function load() {
var list = document.getElementById("list");
list.innerHTML = "";
for (var i=0 ; i<localStorage.length ; i++) {
var key = localStorage.key(i);
list.options[list.options.length] = new Option(localStorage[key], key);
}
}
function remove() {
var list = document.getElementById("list");
if (list.selectedIndex < 0) return; // ์๋ฌด๊ฒ๋ ์ ํ๋์ง ์์๋ค๋ฉด
var selected = list.options[list.selectedIndex].value;
localStorage.removeItem(selected);
load();
}
function add() {
var key = document.getElementById("key").value;
var value = document.getElementById("value").value;
localStorage[key] = value;
load();
}
</script>
</head>
<body>
<h1>Web Storage Test</h1>
<p>
<select id="list" style="width:100px"></select>
<button id="removeBtn">remove</button>
</p>
<p>
key : <input type="text" id="key"> - value <input type="text" id="value">
<button id="addBtn">add</button>
</p>
</body>
</html>
02. ์คํ
(F12๋ฅผ ๋๋ฅด๋ฉด ๋์ด)
----------------------------------------------------------------
WEB SQL Database ๊ตฌํ (W3C ์์ Drop ํ ๋ฉ์๋์)
----------------------------------------------------------------
Drop๋ ์ด์
00. W3C๋ ๋ธ๋ผ์ฐ์ ธ ๋ฐด๋๋ค์๊ฒ ๊ฐ์ ๋ก SQLite๋ฅผ ์ฌ์ฉํ๊ฒ ํ ์ ์๋ ๊ถํ์ด ์์
01. SQL์ ๋ชจ๋ฅด๋ ์ฌ๋๋ค์ํด
02. ํน์ ๋ธ๋ผ์ฐ์ ธ ๋ฐด๋๊ฐ ๋ ์DB๋ฅผ ์๋ฒ ๋๋ ์์ผฐ์๋ SQL๋ฌธ์ด ํ๋ ค์ง ์ ์์
SQLite(RDBMS) - OpenSource, ์์ ์ฑ, ๊ฒฝ๋, ์ด์ฉํธ์์ฑ
- ๋ธ๋ผ์ฐ์ ์ ๋ด์ฅ๋์ด ์์ผ๋ฏ๋ก DB Connectionํ์์์, ๋จ์์ฒ๋ฆฌ, ํธ๋ ์ญ์ ์ฒ๋ฆฌ ๊ฐ๋ฅ
01. ์ค์ฅ
<!DOCTYPE html>
<html>
<head>
<meta charset=EUC-KR">
<title>Insert title here</title>
<script>
// DB ์ด๊ธฐํ
var db = openDatabase("dbtest", "", "DB TEST", "1024*1024");
// Table ์ค๋น
db.transaction(function(tx) {
tx.executeSql("create table if not exists m_tb ("
+ "_id integer primary key autoincrement,"
+ "name not null,"
+ "phone not null)");
});
window.onload = function(){
var removeBtn = document.getElementById("removeBtn");
var addBtn = document.getElementById("addBtn");
removeBtn.addEventListener("click", remove); //removeBtn์ click์ด๋ฒคํธ ๋ฐ์์ removeํจ์ ํธ์ถ
addBtn.addEventListener("click", add); //addBtn์ click์ด๋ฒคํธ ๋ฐ์์ addํจ์ ํธ์ถ
load();
}
// SelectBox ๊ฐฑ์
function load() {
db.transaction(function(tx) {
tx.executeSql("select * from m_tb", [], // ?์ ๋ฃ์๊ฐ
function(tx, rs) { // ์ฑ๊ณต์
var list = document.getElementById("list");
list.innerHTML = "";
var rows = rs.rows;
for (var i=0 ; rows.length ; i++) {
var row = rows.item(i);
list.options[list.options.length] = new Option(row.name, row._id);
}
});
});
var list = document.getElementById("list");
list.innerHTML = "";
for (var i=0 ; i<localStorage.length ; i++) {
var key = localStorage.key(i);
list.options[list.options.length] = new Option(localStorage[key], key);
}
}
function remove() {
var list = document.getElementById("list");
if (list.selectedIndex < 0) return; // ์๋ฌด๊ฒ๋ ์ ํ๋์ง ์์๋ค๋ฉด
var selected = list.options[list.selectedIndex].value;
db.transaction(function(tx) {
tx.executeSql("delete from m_tb where _id=?", [selected], // ?์ ๋ฃ์๊ฐ
function() { // ์ฑ๊ณต์
load();
});
});
}
function add() {
var name = document.getElementById("name").value;
var phone = document.getElementById("phone").value;
db.transaction(function(tx) {
tx.executeSql("insert into m_tb (name,phone) values(?,?)", [name, phone],
function() { // ์ฑ๊ณต์
load();
});
});
}
</script>
</head>
<body>
<h1>Web SQL Database Test</h1>
<p>
<select id="list" style="width:100px"></select>
<button id="removeBtn">remove</button>
</p>
<p>
name : <input type="text" id="name"> - phone <input type="text" id="phone">
<button id="addBtn">add</button>
</p>
</body>
</html>
02. ๊ฒฐ๊ณผ (F12๋ฅผ ๋๋ฅด๋ฉด ๋์ด)
----------------------------------------------------------------
Indexed DB (SQLite์ ๋์) - ์ง์๋๋ ๋ธ๋ผ์ฐ์ ธ๊ฐ ํ์์ ๊ทน์
----------------------------------------------------------------
๊ฐ์ฒด๋ฅผ ๊ตฌ์กฐํ์์ผ ๋ด๋ถ์ ์ผ๋ก๋ ๋ฐด๋๊ฐ ์ด๋ ํ ๋ฐฉ์์ผ๋ก๋ (์:SQLite์ด์ฉ) ๋ธ๋ผ์ฐ์ ธ์ ์ ์ฅ ๊ฐ๋ฅํ๋๋ก ํ๋ ๋ฐฉ์
-------------------------------------------------------------------------------------------------
----------------------------------------------------------------
Communucation API
----------------------------------------------------------------
๋๊ธฐํต์ - ํด๋ผ์ด์ธํธ์์ ์๋ฒ๋ก ๋ฐ์ดํฐ ์์ฒญ์ ๋ธ๋ผ์ฐ์ ์์ ๋ง๋ค์ด์ง request ๋ฐ์ดํฐ๋ฅผ ์๋ฒ์์ ๋ฐ์, ์๋ฒ๋ response
๋ฐ์ดํฐ๋ฅผ ๋ง๋ค์ด ํด๋ผ์ด์ธํธ์๊ฒ ์ ๋ฌํด ์ค๋ค (ํด๋ผ์ด์ธํธ๋ ์๋ฒ์ ์๋ต์ ๋ฐ์ ๋ ๊น์ง, ์ด๋ ํ ๋์๋ ํ ์ ์๋ค)
๋น๋๊ธฐํต์ - AJAX
stateless - client ์ ์์ํ์ ์ง๋ฅผ ์ํด session, cookie, web storage
realtime dataํต์ ๋ถ๊ฐ : C/S ์ปค๋ฅ์ ์ด ๋์ด์ง ์ํ๋ก, ์๋ฒ๋ก๋ถํฐ๋ ํด๋ผ์ด์ธํธ์๊ฒ ๋ฐ์ดํฐ๋ฅผ ์ ์กํ ์ ์๋ค.
๋์ : polling (ํด๋ผ์ด์ธํธ์์ ์ผ์ ์๊ฐ ์๋ฒ์ ์ฐ๊ฒฐ์๋) - ๋คํธ์ ํธ๋ ํฝ ์ด๋
comet : ํด๋ผ์ด์ธํธ์์ ์์ฒญ์ ํ๋ฉด ์๋ฒ๋ ์๋ต์ ํ์ง ์๊ณ ์๋ค๊ฐ ์ด๋ฒคํธ๊ฐ ๋ฐ์๋๋ฉด ์๋ฒ์์ ๊ทธ๋์์ผ
์๋ต์ ํจ - ํด๋ผ์ด์ธํธ๋ ๋๊ธฐํ๋ฉด์ด์ง๋ง innerFrame=0 ๋ถ๋ถ์ผ๋ก ๋๊ธฐ๊ณ ๋ถ๋ชจ์ฐฝ์ผ๋ก ๋๊น
HTML5 ๋์ : web socket (web socket ์ ์ฉ ์๋ฒ๊ฐ ํ์ํจ), server sent event (์ฃผ๊ธฐ์ ์ธ C/S ํต์ )
SameOrigin Policy - ์๋ก ๋ค๋ฅธ ์๋ฒ์์ ํ๋์ ํด๋ผ์ด์ธํธ์ ์ ์๋์์๋ ํด๋ผ์ด์ธํธ์ ์ ๋ณด๋ฅผ ๊ณต์ ํ ์ ์๋ค
(์๋ธ ๋๋ฉ์ธ์ ๊ฒฝ์ฐ๋ ๋ฉ์ธ๋๋ฉ์ธ๊ณผ ๋ค๋ฅธ ๋๋ฉ์ธ์ผ๋ก ์ทจ๊ธ)
๋์ : Cross Document Message
Web Worker - JavaScript Thread Program (node.js, ์๋ฒ:๊ตฌ๊ธ์ V8์์ง) - ๋ชจ๋ฐ์ผ์์ ์๋จ
----------------------------------------------------------------
Crocess Document
----------------------------------------------------------------
์์ดํ ๋๋ฉ์ธ (์๋ก๋ค๋ฅธ ๋๋ฉ์ธ์ ๊ฐ์ง document ๊ฐ์ ๊ฐ์ฒด ์ ์ก์ ์ํ ๊ธฐ์ )
01. ํ๊ฒฝ์ค์
02. Dynamic Web Project ๋ก ํ๋ก์ ํธ ์์ฑ
03. ํ๋ก์ ํธ ์์ฑ ๊ณ์
04. ์๋์ ๊ฐ์ด ์ฝ๋ ์ค์ฅ (์ผ๋จ inner.html ๋ก twitter ์ ๊ฒ์ ๋ด์ฉ ๊ฐ์ ธ์ค๊ธฐ ์์ค ์ง๊ธฐ)
<!DOCTYPE html>
<html>
<head>
<meta charset=EUC-KR">
<title>Insert title here</title>
<script>
// dom node ๊ตฌ์กฐ ์ ๊ทผ์ ํธํ๊ฒ ์ฌ์ฉํ๊ธฐ ์ํ jquery ์คํ์ผ์ ํจ์
function $(id) {
return document.getElementById(id);
}
window.onload = function() {
search();
}
function search() {
$("results").innerHTML = "";
// ๊ฒ์๋ฌธ์์ด
var keyword = "kkang";
// callback : ๊ฒ์ ๊ฒฐ๊ณผ๋ฅผ process๋ก ๋ฐ์ ์ ์๋ ๊ฐ๋ฐ์ ํจ์
var query = "http://search.twitter.com/search.json?callback=process"
+ "&q=";
query += encodeURI(keyword);
// ์กด์ฌํ์ง ์๋ script tag๋ฅผ ๋ง๋ค์ด ์ฌ์ฉํ๊ฒ ๋ค
var script = document.createElement("script");
script.src = query;
// ๋ง๋ค์ด์ง tag๋ฅผ ํค๋ํ ๊ทธ์ ์์๋ ธ๋์ ๋ถ์, ๋ฐ๋ head ์ ๋ณด์ ์ํด ํ์ด์ง๊ฐ ์ด๋ฆผ
document.getElementsByTagName("head")[0].appendChild(script);
}
// twitter ๊ฒ์๊ฒฐ๊ณผ๋ฅผ callback ์ผ๋ก๋ก ์ง์ ํ process ํ์ ์ผ๋ก ํธ๋ค๋ง
function process(response) {
var datas = response.results;
// map : ์งํฉ๊ฐ์ฒด์ ๊ฐฏ์๋งํผ ์ง์ ๋ ํจ์๋ฅผ ํธ์ถ(ํ๋ํ๋ ๋๊น)
var rows = datas.map(function(data) {
// ํ ๊ฑด์ ๋ฐ์ดํฐ๋ก ํ๋ฉด์ ์ฐ์ด์ฃผ๊ธฐ ์ํ html ๊ตฌ์กฐ๋ฅผ ๋ง๋ค์ด ์ฃผ๋ ํจ์ ํธ์ถ
return createResult(data.profile_image_url, data.text);
});
// ํ๋ฉด ์ถ๋ ฅ
rows.forEach(function(row) {
$("results").appendChild(row);
});
}
// ๋์ด์จ ๋ฐ์ดํฐ๋ก ํ๋ฉด์ ์ฐ์ html ๊ตฌ์กฐ๋ฅผ ์์ฑํ๋ ํจ์
function createResult(src, title) {
var p = document.createElement("p");
var icon = document.createElement("img");
icon.src = src;
icon.setAttribute("width" , 48);
icon.setAttribute("height", 48);
// p ํ ๊ทธ ์์ img ํ ๊ทธ๋ฅผ ๋ฃ๊ณ ๋ฌธ์์ด๋ก ๋ง๋ฌ
p.appendChild(icon);
p.appendChild(document.createTextNode(title));
return p;
}
</script>
</head>
<body>
<div id="results"></div>
</body>
</html>
05. ๊ฒ์๊ฒฐ๊ณผ ํ์ธ (์ค์ ํ ๋๋ฉ์ธ์ผ๋ก ๊ฒ์๊ฒฐ๊ณผ๋ฅผ ํ์ธํ๋ค)
๋ณธ๊ฒฉ์ ์ธ crocess document ํ ์คํธ
inner.html
<!DOCTYPE html>
<html>
<head>
<meta charset=EUC-KR">
<title>Insert title here</title>
<script>
// dom node ๊ตฌ์กฐ ์ ๊ทผ์ ํธํ๊ฒ ์ฌ์ฉํ๊ธฐ ์ํ jquery ์คํ์ผ์ ํจ์
function $(id) {
return document.getElementById(id);
}
// outter์์ ๋์ด์ค๋ MessageEvent ์ ํธ์ถ๋ ํจ์
function messageHandler(e) {
if (e.origin == "http://localhost:8080") {
search(e.data);
}
}
window.onload = function() {
//search();
// message ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ๋ค๋ฉด messageHandlerํจ์๋ฅผ ํธ์ถํ๋ผ
window.addEventListener("message", messageHandler);
}
function search(keyword) {
$("results").innerHTML = "";
// ๊ฒ์๋ฌธ์์ด
//var keyword = "kkang";
// callback : ๊ฒ์ ๊ฒฐ๊ณผ๋ฅผ process๋ก ๋ฐ์ ์ ์๋ ๊ฐ๋ฐ์ ํจ์
var query = "http://search.twitter.com/search.json?callback=process"
+ "&q=";
query += encodeURI(keyword);
// ์กด์ฌํ์ง ์๋ script tag๋ฅผ ๋ง๋ค์ด ์ฌ์ฉํ๊ฒ ๋ค
var script = document.createElement("script");
script.src = query;
// ๋ง๋ค์ด์ง tag๋ฅผ ํค๋ํ ๊ทธ์ ์์๋ ธ๋์ ๋ถ์, ๋ฐ๋ head ์ ๋ณด์ ์ํด ํ์ด์ง๊ฐ ์ด๋ฆผ
document.getElementsByTagName("head")[0].appendChild(script);
}
// twitter ๊ฒ์๊ฒฐ๊ณผ๋ฅผ callback ์ผ๋ก๋ก ์ง์ ํ process ํ์ ์ผ๋ก ํธ๋ค๋ง
function process(response) {
var datas = response.results;
// map : ์งํฉ๊ฐ์ฒด์ ๊ฐฏ์๋งํผ ์ง์ ๋ ํจ์๋ฅผ ํธ์ถ(ํ๋ํ๋ ๋๊น)
var rows = datas.map(function(data) {
// ํ ๊ฑด์ ๋ฐ์ดํฐ๋ก ํ๋ฉด์ ์ฐ์ด์ฃผ๊ธฐ ์ํ html ๊ตฌ์กฐ๋ฅผ ๋ง๋ค์ด ์ฃผ๋ ํจ์ ํธ์ถ
return createResult(data.profile_image_url, data.text);
});
// ํ๋ฉด ์ถ๋ ฅ
rows.forEach(function(row) {
$("results").appendChild(row);
});
}
// ๋์ด์จ ๋ฐ์ดํฐ๋ก ํ๋ฉด์ ์ฐ์ html ๊ตฌ์กฐ๋ฅผ ์์ฑํ๋ ํจ์
function createResult(src, title) {
var p = document.createElement("p");
var icon = document.createElement("img");
icon.src = src;
icon.setAttribute("width" , 48);
icon.setAttribute("height", 48);
// p ํ ๊ทธ ์์ img ํ ๊ทธ๋ฅผ ๋ฃ๊ณ ๋ฌธ์์ด๋ก ๋ง๋ฌ
p.appendChild(icon);
p.appendChild(document.createTextNode(title));
return p;
}
</script>
</head>
<body>
<div id="results"></div>
</body>
</html>
outter.html
<!DOCTYPE html>
<html>
<head>
<meta charset=EUC-KR">
<title>Insert title here</title>
<style>
iframe {
width : 800px;
height: 400px;
}
</style>
<script>
window.onload = function() {
var searchBtn = document.getElementById("searchBtn");
searchBtn.addEventListener("click", search);
}
function search() {
var searchTxt = document.getElementById("keyword").value;
// Cross Document ๋ก ๋ฐ์ดํฐ ์ ์ก
document.getElementById("inner").contentWindow.postMessage(searchTxt, "http://www.test.com:8080");
}
</script>
</head>
<body>
<p>
keywork : <input type="text" id="keyword" width="500">
<button id="searchBtn">search</button>
</p>
<p>
<iframe id="inner" src="http://www.test.com:8080/Ch4-Communication/inner.html"></iframe>
</p>
</body>
</html>
๊ฒฐ๊ณผ : outter.html (http://localhost:8080/Ch4-Communication/outter.html) ์ ์คํ์์ผ
inner.html (http://www.test.com:8080/Ch4-Communication/inner.html) ์์ ๊ฒฐ๊ณผ๊ฐ ๋์ค๋ ๊ฒ์ ํ์ธํ๋ค
๋ก์ปฌ ์ฃผ์๋ฅผ ํตํ์ฌ www.test.com:8080 ์์ ์คํ๋ ๊ฒ์ ๊ฒฐ๊ณผ๋ฅผ ๊ฐ์ ธ์จ๋ค.
document.getElementById("inner").contentWindow.postMessage(searchTxt, "http://www.test.com:8080");
๋ก ์ธํ์ฌ ๊ฐ๋ฅ
-------------------------------------------------------------------------------------------------
----------------------------------------------------------------
CANVAS
----------------------------------------------------------------
canvas : pixel
SVG : vector (http://svg-wow.org/)
----------------------------------------------------------------
VIDEO Control (์๋๋ก์ด๋์ ํ๋ธ๋ผ์ฐ์ ์ ๋์์ด ์์ดํ๋ฏ๋ก ์ฃผ์ํ ๊ฒ)
----------------------------------------------------------------
01. ํ๋ก์ ํธ๋ฅผ Dynamic Web Project ๋ก ์์ฑ ํ์ฌ video.html ํ์ผ ์ค์ฅ
<!DOCTYPE html>
<html>
<head>
<meta charset=EUC-KR">
<title>Insert title here</title>
<script>
var video;
window.onload = function() {
var device;
video = document.getElementById("video");
//*******************************************
// user agent ๊ฐ์ผ๋ก ํ ๋๋ฐ์ด์ค์ ์ ๋ณด๋ฅผ ๋ฝ์๋
//*******************************************
var agent = navigator.userAgent;
if (agent.toUpperCase().indexOf("IPHONE") > -1) {
device = "iPhone";
} else if (agent.toUpperCase().indexOf("ANDROID") > -1) {
device = "Android";
// Android4.0 ICS ํฐ(2012.03์ ํ์ฌ ์ต์ ๋ฒ์ )์์์ ๋ธ๋ผ์ฐ์ ๋
// html5 video play ๋ฅผ ํ ์คํฌํ ๋ธ๋ผ์ฐ์ ์ ๋์ผ ๋ฐฉ๋ฒ์ผ๋ก ์ฒ๋ฆฌ
if (agent.toUpperCase().indexOf("ANDROID 4.0") > -1) {
device = "Android4.0";
}
} else {
device = "unKnown";
}
//*********************************************************
// ์ค์ : ์๋๋ก์ด๋์ฉ์ ์ปจํธ๋กค๋ฐ๋ฅผ ๋นผ์ผํจ, ์์ค์ ํ์ ์ ๋นผ์ผํจ
//*********************************************************
if (device == "Android") {
var videodiv = document.getElementById("myvideo");
videodiv.innerHTML = "<video id='video' poster='bbb_poster-360x240.jpg' width='360' height='240'>"
+ " <source src='BigBuck.m4v' />"
+ " <source src='BigBuck.webm' />"
+ " <source src='BigBuck.theora.ogv' />"
+ "</video>"
+ "<p><input type='button' onClick='play()' value='play' /></p>";
}
}
function play(){
video.play();
}
</script>
</head>
<body>
<!-- -----------------------------------------------------
๋ฐ์คํฌํ ๋ธ๋ผ์ฐ์ ๋ iPhone ์์๋ ์๋์ ๊ฐ์ด ์ ์ play๋จ
์๋๋ก์ด๋์ ๊ฒฝ์ฐ๋ source type์ ๋ช ์๋์ด ์์ผ๋ฉด ์๋๊ณ
๋ฐ๋์ javascript์์ play ๋ช ๋ น์ ๋ด๋ ค์ผ ํจ
------------------------------------------------------ -->
<div id="myvideo">
<video id="video" poster="bbb_poster-360x240.jpg" width="360" height="240" controls>
<source src="BigBuck.m4v" type="video/mp4" />
<source src="BigBuck.webm" type="video/webm" />
<source src="BigBuck.theora.ogv" type="video/ogg" />
</video>
</div>
</body>
</html>
02. ํ์ธ