2012. 3. 27. 10:42ㆍ99. 정리전 - IT/12. Javascript
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. 확인