14 강. HTML API [1] : 오프라인웹, 파일접근, 웹스토리지 1. 오프라인웹 1.1 오프라인웹애플리케이션 Ÿ 오프라인상태에서도사용이가능한애플리케이션이다. 온라인지원이안되는곳에서 도웹에접근하여사용이가능하다. 즉파일들을클라이언트에서캐시로저장하여사 용하므로웹문서의접근이빠르다. 1.2 매니페스트파일 Ÿ 오프라인에서도웹사이트이용이가능하도록하기위해서는여러문서와파일들을캐시로저장해야하는데, 캐시에저장할자원의목록이매니페스트파일이다. 어떠한파일을캐시로저장해야하는지를지정하며서버로부터웹문서들과함께다운로드되는파일이다. CACHE MANIFEST #Cache Section CACHE: news.html news.js news.css image.jpg #Network Section NETWORK: new_news.html image_check.jpg 필수적으로첫줄에포함되어야하는내용설명문부분으로 # 로시작하는문자열기본값을나타내는부분으로클라이언트에서캐시되어야할파일들을지정한다. ( 오프라인에서도해당파일에접근이가능하다.) 반드시온라인상태에서만접근할수있는파일을지정한다. #Fallback Section FALLBACK:./news image_notice.jpg 대체되는자원을지정하는부분이다. ( 클라이언트에서서버로페이지요청을하였을경우해당페이지가존재하지않을때대신표시할자원을지정한다.) 1.3 캐시매니페스트작성 Ÿ 매니페스트파일은클라이언트에서접근할수있어야하기때문에파일의 MIME 타입 을웹서버의 mime.types 파일에지정해야한다. text/cache-manifest manifest - 1 -
Ÿ 애플리케이션문서에서매니페스트파일을다음과같이지정한다. <!DOCTYPE html> <html manifest=" 매니페스트파일이름 ( 예 : cache.manifest)"> </html> Ÿ 매니페스트파일을지정하면해당문서호출이후부터캐시가동작하게된다. 그리고해당문서는 CACHE 섹션에서지정하지않아도자동으로캐시가된다. 1.4 오프라인접근예제 cache.html <!DOCTYPE html> <html manifest="cache.manifest"> <head></head> <body> <div> <table> <tr> <td><img src="flower1.jpg"></td> <td><img src="flower2.jpg"></td> </tr> </table> </div></body> </html> cache.manifest CACHE MANIFEST # Version 1.0.0.0 CACHE: flower1.jpg NETWORK: flower2.jpg 오프라인에서의실행결과 1.5 이벤트처리 Ÿ 좀더세세한동작제어를위해서는이벤트나캐시의상태에따른처리가필요하다. Ÿ 매니페스트가업데이트되고유지되도록여러이벤트가 applicationcache 객체에서발 생하여 사용자에게 캐시 업데이트의 상태에 대해 적절하게 알릴 수 있다. applicationcache 객체에서 status속성및 update(), swapcache(), abort() 메소드를사 용할수있다. Ÿ 애플리케이션캐시상태에따른처리로 status 속성을사용하여현재의캐시상태를 확인할수있다. - 2 -
var appcache = window.applicationcache switch ( appcache.status ) { case appcache.uncached: // 캐시하지않을경우에대한처리 case appcache.idle: // 최신의캐시이용상태일경우에대한처리 case appcache.checking: // 캐시의업데이트체크중일경우에대한처리 case appcache.downloading: // 캐시의업데이트중일경우에대한처리 case appcache.updateready: // 최신캐시를이용할수있는상태에대한처리 case appcache.obsolete: // 캐시가되지않은상태에대한처리 Ÿ applicationcache 객체에서발생하는이벤트이벤트설명업데이트여부를확인하거나, 처음으로매니페스트를다운로드하려고할 checking 때 error 오류로인하여업데이트종료 noupdate 매니페스트가업데이트되지않음 downloading 브라우저에서업데이트할것을찾아서가져오고있을때 progress 매니페스트에기록된자원을다운로드하려고할때 updateready 매니페스트에기록된자원이새롭게다운로드되었을때 cached 자원이다운로드되어캐시에저장된상태 obsolete 매니페스트를가져오는데실패하여캐시가제거될때 Ÿ 이벤트에따른처리 window.applicationcache.onchecking = function(e) { window.applicationcache.onnoupdate = function(e) { window.applicationcache.ondownloading = function(e) { window.applicationcache.addeventlistener("checking", handlecacheevent, false); window.applicationcache.addeventlistener("noupdate", handlecacheevent, false); window.applicationcache.addeventlistener("downloading", handlecacheevent, false); function handlecacheevent (e) { - 3 -
1.6 브라우저의온라인 / 오프라인상태검사 Ÿ window.navigator.online 속성 <script> function updateindicator () { document.getelementbyid('indicator').textcontent=navigator.online?' 온라인 ': ' 오프라인 '; </script> <body onload="updateindicator()" ononline="updateindicator()" onoffline="updateindicator()"> <p> 현재네트워크의상태는 : <span id="indicator">( 알려져있지않습니다 )</span> </body> 2. 파일접근 2.1 파일 API Ÿ 웹개발자가확장또는플러그인없이안전하게클라이언트컴퓨터의로컬파일에접근가능하다. 읽기전용으로수정및삭제가불가하다. 사용자가드래그앤드롭한파일이나 input 요소의 type= file 에서선택한파일은읽기가능하다. 2.2 파일인터페이스 : 파일정보얻기 Ÿ 스크립트를통해서파일에접근하기위해서는 FileList라는객체를통해야한다. 만일드래그앤드롭이라면드롭이벤트객체에서얻을수있는 DataTransfer 객체의 files 속성으로가져와야하고, input 요소라면 input 요소객체의 files 속성에서가져온다. Ÿ 정보를알고자하는파일의객체를구하기위해서는선택한파일의객체가저장되어있는 FileList객체를구하면되는데, FileList 객체는배열형식으로되어있기때문에인덱스를지정해서파일객체를가져온다. Ÿ FileList 객체는드래그앤드롭에서는드롭되었을때얻을수있고, input 요소에서는사용자가파일을선택했을때 change 이벤트를통해서얻을수있다. Ÿ 파일과관련된정보는 name( 파일명 ), type( 파일속성 ), size( 파일크기 ), lastmodifieddate ( 파일이마지막으로수정된날짜 ) 속성을통해얻을수있다. 예제파일정보확인 <!DOCTYPE html><html><head> <script> function fileinfo(){ var file = document.getelementbyid("file").files[0]; var table = document.getelementbyid("table"); table.innerhtml = "<tr><td> 파일이름 </td><td>" + file.name + "</td></tr>"; - 4 -
table.innerhtml += "<tr><td> 파일크기 </td><td>" + file.size + "</td></tr>"; table.innerhtml += "<tr><td> 파일타입 </td><td>" + file.type + "</td></tr>"; table.innerhtml += "<tr><td> 파일수정날짜 </td><td>" + file.lastmodifieddate + "</td></tr>"; </script> </head> <body> <h2> 로컬파일정보확인하기 </h2> <input id="file" type="file" onchange="fileinfo()"> <table id="table"></table> </body> </html> 2.3 파일리더인터페이스 : 파일내용읽기 Ÿ 메모리에 File 객체를읽기위한방법으로 FileReader 객체사용한다. 1. 객체를생성한다. var 변수 = new FileReader(); 2. 객체의메서드를사용하여파일내용을문자열로변환하여저장한다. 3. 이벤트처리를통해변환하여저장된파일의내용을반환한다. Ÿ FileReader 객체의메서드및속성은다음과같다. readystate : FileReader 객체의상태를반환한다. result : 읽기가완료되었을때의유효한콘텐츠 ( 파일내용 ) 를반환한다. error : 읽기도중에발생하는오류를반환한다. abort() : 파일읽기를중단한다. readasarraybuffer(file) : 파일의내용을읽어 ArrayBuffer 객체로변환하여저장한다. readastext(file, encoding) : 파일의내용을읽어지정한인코딩방식 ( 기본 : URF-8) 의텍스트로저장한다. readasdataurl(file) : 파일의내용을읽어 Data URL 형식의문자열로변환하여저장한다. Ÿ FileReader 객체에서발생하는이벤트핸들러 onloadstart : 데이터를읽기시작했을때발생한다. onprogress : 데이터를읽고있는도중에연속으로발생한다. onabort : 데이터읽기가중단 (abort() 호출 ) 되었을때발생한다. onerror : 데이터읽기가실패했을때발생한다. onload : 데이터읽기를성공적으로완료했을때발생한다. onloadend : 데이터읽기요구가완료 ( 성공 / 실패와는무관 ) 했을때발생한다. - 5 -
예제파일내용읽기 <!DOCTYPE html> <html><head> <script> document.addeventlistener("domcontentloaded", function() { var input = document.getelementbyid('file'); var view = document.getelementbyid("content"); input.addeventlistener("change", function(event) { var file = event.target.files[0]; if (!file) { return; var reader = new FileReader(); //FileReader 객체를생성 reader.readastext(file, "utf-8"); // 데이터를읽는다. reader.onload = function() { // 파일데이터를성공적으로읽기완료되면 view.textcontent = reader.result; // 텍스트영역에내용을표시한다. ; reader.onerror = function(event) { switch(event.target.error.code) { //FileReader 객체의오류값 case error.not_found_err: alert(" 읽을파일을찾지못하였습니다.."); case error.security_err: alert(" 보안상안전하지않습니다.."); case error.abort_err: alert(" 읽기가중지되었습니다."); case error.not_readable_err: alert(" 읽기권한이없습니다."); case error.encoding_err: alert(" 파일용량이상한을초과하였습니다."); ;, false);, false); </script> </head> <body> <h2> 로컬파일읽기 </h2> <input id="file" type="file" /> <textarea id="content" readonly style="width:600px; height:200px;"></textarea> </body> </html> 2.4 URL 인터페이스 Ÿ 드래그앤드롭이나 input 요소에서가져온파일에고유 URL 를생성하거나삭제하기 - 6 -
위한메서드들을제공한다. 생성된 URL을특정요소 (img, video 등 ) 의 src 속성에직접지정가능하다. 예제 <!DOCTYPE html> <html><head> <script> document.addeventlistener("domcontentloaded", function() { var input = document.getelementbyid('file'); input.addeventlistener("change", function(event) { var file = event.target.files[0]; if (!file) { return; var url = window.url.createobjecturl(file); // 고유한 URL을생성 var img = document.createelement("img"); img.src = url img.width = 400; img.height = 300; document.body.appendchild(img);, false);, false); </script></head><body><input id="file" type="file" /></body></html> 3. 웹스토리지 3.1 웹스토리지 Ÿ 기존에는클라이언트에간단한정보를저장하기위해서주로쿠키 (cookie) 를사용하였 다. 일반적으로서버에서는여러웹사이트를옮겨다니는사용자정보를알아내기위 해서쿠키들을넣어두고이값들을활용한다. Ÿ 웹스토리지는클라이언트에데이터를저장하기위한저장영역이다. 쿠키 웹스토리지 저장용량 4KB 도메인당 5MB 로명세서에서권장 서버로요청이갈때마다 HTTP 헤더에네트워크전송서버로요청을하더라도 HTTP 메시지에담겨서전송하여불필요한네트워크부부하및보안는포함되지않아부하를줄일수있다. 하및보안취약하다. 유효기간유효기간이존재하여자동삭제된다. 세션문제 사용방법 동일한사이트라할지라도다른정보를 가지고작업하는것이불가하다. 복잡 유효기간이없어사용자에의해삭제된 다. 세션스토리지는각창마다독립적인데 이터가저장된다. localstorage.name = myname ; var value = localstorage.name; 데이터형식문자열형식의값만저장가능어떠한형식의데이터값도저장가능 Ÿ 웹스토리지저장데이터는 (key, value) 로구성되어있다. 용도에따라로컬스토리지, - 7 -
세션스토리지로나눌수있다. Ÿ 세션스토리지와로컬스토리지의사용방법은동일하고, 의미와동작의차이가있다. 로컬스토리지 localstorage 데이터저장기간에제한없어영구적보관이가능하다. 도메인마다별도의저장영역을생성한다. 도메인마다생성된스토리지에서로접근불가하고, 같은도메인에속해있는웹페이지들은모두접근이가능하다. 세션스토리지 sessionstorage 데이터저장기간이제한되어세션이종료되 면자동폐기된다. 각세션마다별도의저장영역을생성한다. 같은도메인이라고해도다른윈도우에서생성 되면서로의스토리지에접근이불가하다. Ÿ 다음은웹스토리지의지원여부를판단할수있는코드이다. if ( typeof(storage)!== "undefined" ) { // 이곳에세션및로컬스토리지기능을구현 else { // 웹스토리지기능을지원하지않는경우 3.2 데이터저장, 읽기, 삭제 키 : computer, 값 : programming 저장 읽기 삭제 localstorage.setitem(key, value); localstorage.key = value localstorage[key] = value 변수 = localstorage.getitem(key); 변수 = localstorage.key 변수 = localstorage[key]; localstorage.removeitem(key); delete localstorage.key delete localstorage[key]; localstorage.setitem("computer", "programming"); localstorage.computer = "programming"; localstorage["computer"] = "programming"; var value = localstorage.getitem("computer"); var value = localstorage.computer var value = localstorage["computer"]; localstorage.removeitem("computer"); delete localstorage.computer; delete localstorage["computer"]; - 8 -
window.onload = function() { if ( window.localstorage ) { // 로컬스토리지지원여부 localstorage.setitem("computer", "programming"); // data 저장 localstorage.java = "programming"; localstorage["htmlxml"] = "web programming"; var value = localstorage.getitem("computer"); //data 읽기 alert(value); // programming alert 화면출력 localstorage.removeitem("computer"); //data 삭제 var value = localstorage.getitem("computer"); alert(value); //null alert 화면출력 크롬개발자도구 맞춤설정및제어 - 도구더보기 개발자도구 Resources 를통해서 localstrorage, Session Storage 정보를확인할수있다. - 9 -
예제로컬스토리지 <!DOCTYPE html> <html><head> <script type="text/javascript"> function setdata() { var key = document.getelementbyid("key"); var data = document.getelementbyid("data"); localstorage.setitem(key.value, data.value); alert(" 데이터저장이완료되었습니다."); 저장 function getdata() { var key = document.getelementbyid("key"); var data = localstorage.getitem(key.value); alert(" 조회한데이터값은 "+data+ " 입니다."); 조회 function removedata() { localstorage.clear(); alert(" 모든데이터를삭제하였습니다."); 삭제 function viewdata() { var data = document.getelementbyid("result"); data.value = ""; for(var i = 0; i < localstorage.length; i++) { var key = localstorage.key(i); data.value += localstorage[key] + ","; </script> 모두보기화면 </head> <body> 키 : <input type="text" id="key"><br> 값 : <input type="text" id="data"><br><br> <input type="button" onclick="setdata()" value=" 저장 "> <input type="button" onclick="getdata()" value=" 조회 "> <input type="button" onclick="removedata()" value=" 모두삭제 "> <hr> <input type="button" onclick="viewdata()" value=" 모두보기 "><br> <textarea id="result" cols="30" rows="5"></textarea> </body> </html> - 10 -
3.3 로컬스토리지 vs 세션스토리지 버튼 5 번클릭 첫번째방문 / 5 번표시 브라우저 종료후 재실행 버튼 5 번클릭 두번째방문 / 10 번표시 버튼 5 번클릭 첫번째방문 / 5 번표시 버튼 1 번클릭 첫번째방문 / 1 번표시 3.4 스토리지이벤트 Ÿ 웹스토리지변경에대해서는 window 객체가 storage 이벤트를발생시킨다. Ÿ 스토리지이벤트는 HTTP 프로토콜을통해서만확인가능하다. ( file:// 실습코드파일.html 와같은테스트는불가하다. ) window.addeventlistener("storage", function(event) { var key = event.key ; // 변경된키를표시 var newvalue = event.newvalue; // 변경된후의새로운값을표시 var oldvalue = event.oldvalue; // 변경된키의이전값을표시 var url = event.url ; // 키가변경된문서의 URL 표시 // 이벤트핸들처리, false ); - 11 -