Ajax - Debug Console 만들기

Published on: 2009. 11. 13. 01:40 by louis.dev

보통 Ajax 코딩을 하다 보면 값이 제대로 넘어왔는지 넘어 갔는지를 확인 하기 위해서는 alert()창을 이용해서 찍어야 하는데 이러한 방식은 항상 확인 버튼을 눌러줘야 하기 때문에 불편하다.

그렇기 때문에 log를 만드는 js파일을 생성하고 페이지 마다 다음을 추가하여 로그를 페이지에 남기면 좋다.

<head>테그 사이에
<script type="text/javascript" scr="ajaxLog.js 파일의 경로"></script>
라고 써주고
<body>테그 사이에
<div id="debugConsole"></div>태그를 넣어준다. 항상 id는 debugConsole이라고 정의해야 한다..ㅎㅎ

그리고 자바스크립트 영역에서 log function을 불러다가 쓰면 된다..
ex) log("버그 시작");

출처: 최범균의 Ajax programing

Ajax - XSLT 사용하기

Published on: 2009. 7. 13. 15:40 by louis.dev


Ajax를 사용할때 보통은 xml데이터를 사용하고 노드 탐색을 하여 데이터를 검출한뒤 사용할 곳에 직접 넣어 사용하는 방식을 취한다.

이렇게 되면 직접 style-sheet를 선언해야 하고 또한 매우 복잡한 형태가 된다.

그래서 XSLT 사용한다. XSLT는 실제적으로 보면  XML 데이터지만 거기에 html과 같은 태그와 함께 style-sheet까지 적용되어서 xml데이터만 연동할때 보다 훨신 편하게 xml데이터를 적용할 수 있게 된다.


다음 그림은 struts 2와 Ajax의 실행 순서를 그린 그림이다.
① fun1() function이 실행 되면 Ajax Engine으로 가서 다음과 같은 로직을 탄다.
② 모든 데이터를 수행하면 response XML을 통해 XML데이터를 리턴하게 된다.
③ XML 파일은 callback함수로 넘어간다.
④ fun2() function은 fun3() function을 호출하여 xsl 파일을 호출하고 XSLT로 가서 UI를 생성하고 그 데이터를 fun4() funtion으로 리턴하게 된다.

작업순서

1. xml 파일이 xsl로 가야 하기 때문에 XML을 만드는 작업을 먼저 해야 한다.

var xmlDoc = null; //변수 하나는 xml을 얻기 위해
var xslDoc = null; //xsl을 얻기 위해
 
  function loadList(num,goods) { //goods 파일 이름
      qty = document.buyform.qty[parseInt(num)].value;
      if(parseInt(qty) > 10 || parseInt(qty) < 1){
       alert('1 ~ 10개까지 구입이 가능합니다.');
       document.buyform.qty[parseInt(num)].focus();
       return;
      }
   param = "goods="+goods+
        "&name="+document.buyform.name.value +
        "&qty="+qty;
   sendRequest("cart.action", param, loadedCartXML, "POST");  //sendRequest는 httpRequest.js 에 있는 method
                                                                                                         //cart.action으로 데이터를 전송하고 다음 메소드인 loadedCartXML 
                                                                                                         //을 callback한다.
  }
  
  function loadedCartXML() {
   if (httpRequest.readyState == 4) {
    if (httpRequest.status == 200) {
     xmlDoc = httpRequest.responseXML;                     //전송된 xml데이터를 xmlDoc라는 변수에 저장한다.
     sendRequest("cart.xsl", null, loadedCartXSL, "POST");      //xsl파일로 이동하고 callback으로 loadCartXSL로 이동한다.
    }
   }
  }
  function loadedCartXSL() {
   if (httpRequest.readyState == 4) {
    if (httpRequest.status == 200) {
     xslDoc = httpRequest.responseXML;                                 //xsl에서 수행한 데이터도 xml데이터기 때문에 responseXML로 받는다.
     doXSLT();
    }
   }
  }
  
  function doXSLT() {
   if (xmlDoc == null || xslDoc == null) return;
   
   var list = document.getElementById("cartList");
//internet explorer 일때
   if (window.ActiveXObject) {
    list.innerHTML = xmlDoc.transformNode(xslDoc);                  //transformNode()메소드로 xsl결과를 출력한다.
//explorer가 아닐때  
 } else {
    var xsltProc = new XSLTProcessor();
    xsltProc.importStylesheet(xslDoc);
    var fragment = xsltProc.transformToFragment(xmlDoc, document);
    list.appendChild(fragment);
   }
  }

2. xsl파일이 XSLT로 가려면 중간에 DTD문서가 존재해야 한다.(DTD문서는 확장자는 dtd, xsl파일이름과 같은 경로,같은 이름이어야 한다)
xml 데이터가 다음과 같다면
-------------------------------------------------------------------------------------------
<?xml version="1.0" encoding="euc-kr" ?>
<%@ page contentType="text/xml; charset=EUC-KR"%>
<%@ taglib prefix="s" uri="/struts-tags"%>

<cartlist>
 <s:iterator value="cartlist">
  <cart id="${filename}">
   <goods>${goods}</goods>
   <qty>${qtystr}</qty>
   <cost>${coststr}</cost>
   <amount>${amountstr}</amount>
   <filename>${filename}</filename>
     </cart>
 </s:iterator>
  <qtysum>${qtySum}</qtysum>
  <amountsum>${amountSumstr}</amountsum>
</cartlist>
-------------------------------------------------------------------------------------------
dtd문서는
-------------------------------------------------------------------------------------------
<?xml version="1.0" encoding="euc-kr"?>

<!ELEMENT cartlist (cart*)> <!-- cartlist안에 cart라는 eliment *(0개 이상) -->
 <!ELEMENT cart (goods, qty, cost, amount, filename*, qtysum*, amountsum*)> <!-- cart 라는 element들은 ()안과 같은 노드들을 가지고 있다. *는 0개 이상이란 뜻 -->
   <!ELEMENT goods (#PCDATA)>
  <!ELEMENT qty (#PCDATA)><!--pcdata: 값을 가지고 있다. -->
  <!ELEMENT cost (#PCDATA)>
  <!ELEMENT amount (#PCDATA)>
  <!ELEMENT filename (#PCDATA)>
  <!ELEMENT qtysum (#PCDATA)>
  <!ELEMENT amountsum (#PCDATA)>
<!ATTLIST cart id CDATA #REQUIRED> <!-- card id가 존재하는데 #REQUIRED로 (꼭필요하다)-->

-------------------------------------------------------------------------------------------
다음과 같이 설정한다.


3. 실제 UI가 발생할 xsl파일을 생성한다.
cart.xsl
-------------------------------------------------------------------------------------------
<?xml version="1.0" encoding="euc-kr" ?>
 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:output method = "html" indent="yes" encoding="euc-kr" />
  <xsl:template match="cartlist"> <!-- dtd문서에서 cartlist를 연결시켜줌 -->
<!-- 가장 최상위 eliement를 설정해 준다. -->
    <table border="0" cellpadding="0" cellspacing="1" bgcolor="#c0c0c0">
     <tr height="24" bgcolor="#f0f0f0">
       <td width="50" align="center"><span style="font:10pt"><b>선택</b></span></td>
       <td width="100" align="center"><span style="font:10pt"><b>상품명</b></span></td>
       <td width="52" align="center"><span style="font:10pt"><b>수량</b></span></td>
       <td width="90" align="center"><span style="font:10pt"><b>구입단가</b></span></td>
       <td width="95" align="center"><span style="font:10pt"><b>구입금액</b></span></td>
     </tr>
     <xsl:for-each select="cart">
   <tr height="24" bgcolor="#ffffff">
    <td align="center">
     <span style="font:10pt">
        <input type="checkbox" name="items" value="{filename}"/> 
     </span>
    </td>
   <td align="center">
      <a href="javascript:cartInfo('{filename}','{qty}','{cost}','{amount}')">
       <span style="font:10pt"><xsl:value-of select="goods"/></span>
      </a>  
    </td>
      
    <td align="center"><span style="font:10pt"><xsl:value-of select="qty"/></span></td>
    <td align="right"><span style="font:10pt;padding-right:5px"><xsl:value-of select="cost"/></span></td>
    <td align="right"><span style="font:10pt;padding-right:5px"><xsl:value-of select="amount"/></span></td>
   </tr>   
  </xsl:for-each>
   <tr height="24" bgcolor="#f0f0f0">
    <td align="center"><input type="button" value="삭제" onclick="delproc()"/></td>
    <td align="center"><span style="font:10pt"><b>항목별 합계</b></span> </td>
    <td align="center">
       <span style="font:10pt; color:#ff795a">
      <xsl:value-of select="qtysum"/>
       </span>
    </td>
    <td align="center"><span style="font:10pt">-</span> </td>
    <td align="right">
       <span style="font:10pt; color:#ff795a;padding-right:9px">
       <xsl:value-of select="amountsum"/>
       </span>
    </td>
   </tr>
 </table>
  </xsl:template>
</xsl:stylesheet>
-------------------------------------------------------------------------------------------
- for-each : 반복되는 데이터를 가져온다.
value-of select = xml문서의 다음과 같은 이름의 데이터를 가져온다.

Ajax - Ajax 기본 구동 원리

Published on: 2009. 7. 13. 13:55 by louis.dev

Ajax는 비동기식 통신 방식을 이용하여 페이지 이동없이 페이지를 변환 할 수 있는 기술이다. Ajax는 event에 의해 발행되기 때문에 event발생후 다른 작업을 할 수 있다.

▶ 장점
 - 페이지 이동 없이 고속으로 화면을 전환할 수 있다. 
 - 서버 처리를 기다리지 않고, 비동기 요청이 가능하다. 
 - 수신하는 데이터 양을 줄일 수 있고 클라이언트에게 처리를 위임할 수도 있다.

▶ 단점
 - Ajax를 쓸 수 없는 브라우저에 대한 문제가 있다. 
 - Http클라이언트의 기능이 한정되어 있다. 
 - 페이지 이동 없는 통신으로 인한 보안상의 문제 
 - 지원하는 Charset이 한정되어 있다. 
 - 스크립트로 작성되므로 Debugging이 용이하지 않다. 
 - 요청을 남발하면 역으로 서버 부하가 늘 수 있음.


작동 순서
① jsp의 메인페이지에서 어떠한 이벤트가 발생된다.
② 발생한 이벤트는 script를 실행 시키고 ajax engine 으로 데이터를 전달한다.
③ Ajax engine은 request 객체를 생성하여 WAS로 보내주고 요청한 a.jsp파일을 찾는다.
④ WAS는 request를 분석하여 전달될 a.jsp페이지가 text페이지 인지 아니면 xml 데이터인지를 판단하여 적당한 데이터를 response에 데이터를 실어 보내고 결국 script부분으로 돌아온다.
⑤ 전달된 데이터를 원하는 위치에 삽입한다.

Ajax의 핵심
1. XMLHttpRequest Object 생성

윈도우판 IE에서 XMLHttp Object 생성하는 클래스
obj = new ActiveXObject("Microsoft.XMLHTTP")
obj = new ActiveXObject("MSXML2.XMLHTTP")

윈도우판 IE 이외에서 XMLHttp Object를 생성하는 생성자
obj = new XMLHttpRequest()

---------------------------------------------------------------------------------
function getXMLHttpRequest() {
 if (window.ActiveXObject) {
  try {
   return new ActiveXObject("Msxml2.XMLHTTP");
  } catch(e) {
   try {
    return new ActiveXObject("Microsoft.XMLHTTP");
   } catch(e1) { return null; }
  }
 } else if (window.XMLHttpRequest) {
  return new XMLHttpRequest();
 } else {
  return null;
 }
}
---------------------------------------------------------------------------------

2. open method

obj.open(method, url, [async, [user, [ password ]]])
- obj는 위에서 생성한 XMLHttpRequest 객체

설명 : 요청을 초기화해서 HTTP 메소드 및 URL 등을 설정하는 메소드

method : GET/POST
url : 요청대상 url
       async(옵션) : 비동기 true, 동기 false (default : true)
       user(옵션) : 인증페이지에서 사용될 사용자 이름
       password(옵션) : 인증페이지에서 사용될 암호

- POST 방식 :
                     obj.open( 'POST', 'http://www.myweb.net/' )
                     send('data=1')

send에 파라미터로 전달될 값을 넣어준다.
예) send('userId="user01"&'userPw="123"'')

- GET 방식 :
                   obj.open( 'GET', 'http://www.myweb.net/', true, id, password )
                   send(null)

3. 요청 헤더 설정
setRequestHeader(header, 값)
설명 : 인수로 지정한 요청 헤더를 설정하는 메소드, open() 메소드가 먼저 호출되어야함.
open() 메서드와 send() 메서드 사이에 위치하여야 함.
header : 검색하고 싶은 헤더 이름
값 : 설정하고 싶은 값

예)obj.open( 'POST', 'http://www.myweb.net/' )
    obj.setRequestHeader( 'Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8')
    send('~~~~')

4. Http 요청 송신
send(body)
설명 : 요청을 송신하는 메소드

예)  var str = 'data=aaa&test=10'
      send(str)

5. 착신
요청이 송신되면 서버로부터 그에 대한 응답이 도착하는데, 언제 도착할지 모를때 이를 확인하기 위해 onreadystatechange이벤트를 이용한다.

obj.onreadystatechange = 핸들러 함수 이름
function 핸들러 함수 이름(obj)
 
예)
obj.onreadystatechange = func1
function func1() {
       if ( obj.readyState == 4 ) {
            alert(obj.responseText);
       }
}

readyState 값이 변화할때 데이터를 얻어 온다.

데이터가 정확히 처리 되었는지 안되었는지 확인 하는 방법

- readyState



위와 같은 표값으로 처리가 되었는지 안되었는지 확인 할 수 있다.

- status
3자릿수의 숫자(long)로 HTTP상태 코드를 나타내는 프로퍼티, send()가 성공한 뒤에 얻어낼 수 있다.


- statusText
HTTP상태 텍스트(영문)를 나타내는 프로퍼티
Opera 8에서는 "undefined"가 반환된다. 따라서, 크로스 브라우저를 실현하는 경우에는 statusText보다 status 쪽이 안전하다.

예)
obj.onreadystatechange = function () {
    if (obj.readState == 4 && obj.statusText == "OK") {
       alert(obj.responseText)
    }
}

보통의 방식
obj.onreadystatechange = function () {
    if (obj.readState == 4 && obj.status == 200) {
       alert(obj.responseText)
    }
}


5. 데이터

- xml 파일로 데이터를 받는 형식

xmlobj = obj.responseXML
요청에 대한 응답을 XML(DOMDocument)로 반환한 프로퍼티
xmlobj : XML 문서(Object data Type)
   
if (obj.readState == 4) {    //데이터 로딩이 되었으면
       // 응답을 취득
        var xmlDoc = oj.responseXML      //XML데이터를 전송 받겠다.
       // test tag를 배열로 set
        var nodes = xmlDoc.getElementsByTagName("test")    //XML문서에서 TAG NAME이 test인것의 정볼르 nodes에 저장한다.
       // 최초 test tag의 firstChild 값을 표시한다.
       alert(nodes[0].firstChild.nodeValue)                            //test라는 첫번째 노드[0]에서,첫번째 eliment[firstChild],값[nodeValue]
    }


jsp로 xml을 만들려면 다음과 같이 선언해야 한다.
<?xml version="1.0" encoding="euc-kr" ?>
<%@ page  contentType="text/xml; charset=EUC-KR"%>


- text 파일로 데이터를 받는 형식

value = obj.responseText
요청에 대한 응답을 텍스트로 돌려주는 프로퍼티

obj.onreadystatechange = function () {
    if (obj.readState == 4) {
       alert(obj.responseText)
    }
}

jsp페이지에서 text로 데이터를 전달 하려면 다음과 같이 선언해야 한다.
<%@ page contentType="text/plain; charset=euc-kr" %>

Ajax - Ajax의 XMLHTTPRequest 객체 생성의 일반적 루틴

Published on: 2009. 4. 2. 02:24 by louis.dev

<script type="text/javascript">
//1.XMLHTTPRequest 가 생성 되었는지 안되었는지 알아보는 변수를 선언
var xmlRequest = false;

//2.XMLHTTPRequest 가 생성 되었는지 안되었는지 체크하는 실질적 메소드 선언
function ajaxInit() {
 if (xmlRequest == null || !xmlRequest) {
  xmlRequest = getXMLHttpRequest();
 }
}

//3.위의 메소드에서 XMLHTTPRequest 객체가 생성이 안되있으면 getXMLHttpRequest() 를 불러 객체 생성
// 참조:: http://javastore.tistory.com/entry/Ajax-브라우저에-따라-XMLHTTPRequest-객체-생성하기

function getXMLHttpRequest() {
 var request = false;
 try {
   request = new XMLHttpRequest();
 } catch (trymicrosoft) {
   try {
     request = new ActiveXObject("Msxml2.XMLHTTP");
   } catch (othermicrosoft) {
     try {
       request = new ActiveXObject("Microsoft.XMLHTTP");
     } catch (failed) {
       request = false;
     }
   }
 }

 if (!request) {
  alert("Error initializing XMLHttpRequest!");
 }
 return request;
}


</script>