Java Script
AJAX
2007. 7. 18.
안혁
http://hyok.kr

.참고문헌
 - Beginning Ajax with ASP.NET <Wrox>


 
이전에 자바스크립트에서 HTTP 요청을 시도해보았습니다. 이번에는 요청해서 받은 XML으로 접근하는 것에 대하여 이야기 하겠습니다. 이전에 CommonAJAXLibrary.js 작성했었는데, 조금 추가된 것이 있어서 먼저 내용을 반영하고 진행하였으면 합니다. 8, 9번째 줄이 추가된 줄입니다
.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
 


 
// Common values for the ReadyState of the XMLHttpRequest object

var READYSTATE_UNINITIALIZED    = 0;
var READYSTATE_LOADING           = 1;
var READYSTATE_LOADED            = 2;
var READYSTATE_INTERACTIVE      = 3;
var READYSTATE_COMPLETE        = 4;
   
// Common values for HTTP status codes
var HTTPSTATUS_OK = 200;

// XML HTTP Request 객체 생성, 반환
function CreateXmlHttpRequestObject()
{ 
    if(window.XMLHttpRequest) 
        xmlHttpObj = new XMLHttpRequest(); // for non-MS browsers 
    else 
    {
       
// for MS browser by version.
 
        try 
        { 
            xmlHttpObj = new ActiveXObject("Microsoft.XMLHTTP"); 
        } 
        catch(e) 
        { 
            xmlHttpObj = new ActiveXObject("Msxml2.XMLHTTP"); 
        } 
    } 
   
    return xmlHttpObj;
}
 


 
다음은 호출하게 DataFile.xml 내용입니다. 이전에 사용했던 XML 갈은 내용입니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
 


<?xml version="1.0" encoding="utf-8" ?>
<Customers> 
  <Customer> 
    <Firstname>Foe</Firstname> 
    <Lastname>Bloggs</Lastname> 
    <email>joe@bloggs.com</email> 
  </Customer> 
  <Customer> 
    <Firstname>Alen</Firstname> 
    <Lastname>Anonymous</Lastname> 
    <email>anon@ymous.com</email> 
  </Customer>
  <Customer>
 
    <Firstname>Marvin</Firstname> 
    <Lastname>Martian</Lastname> 
    <email>marvin@mars.com</email> 
  </Customer>
</Customers>


 
그러면, HTML 먼저 작성해봅시다. 화일명은 마음에 드는 것으로 하세요.

 
1
2
3
4

5
6
7
8
9
10

11
12
13
14
 

   
<body onload="LoadCustomers();"> 
    <form id="form1"> 
    <div> 
        <select id="ddlCustomers" onchange="DisplayCustomerDetails
();">
 
            <option value="">- Select a Customer -</option> 
        </select> 
        <hr /> 
        <div> 
            <p>Details:</p> 
            <span id="spnDetailDisplay">(You have no made a selection yet.)</span> 
        </div> 
    </div> 
    </form>
</body>


 1 : HTML
페이지가 웹브라우저에서 열리면 LoadCustomers() 함수가 호출됩니다. 함수에서 동기식으로 XML 호출할 것입니다.
 4 : <select>
테그, 드롭다운 리스트 초기값은 하나밖에 없지만 LoadCustomers() 의해 동적으로 추가될 것입니다. 값을 선택하게 되면 DisplayCustomerDetails() 함수가 호출됩니다. 함수는 비동기식으로 XML 호출할 것입니다.
 10 : DisplayCustomerDetails()
함수에 의해 <span> 테그 내부의 값이 변경되게 됩니다. <select> 테그에서 선택된 값을 기준으로 체워질 값이 결정됩니다.
 
전체적 흐름을 이해했다면, 이제 LoadCustomers() 함수에 대하여 설명하겠습니다
.

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

21
22

23
24
25
26
27
28
29
30
31
32
33


34
35
36
37
38
39
40
41

42
43
44

   
    <script type="text/javascript" src="./CommonAJAXLibrary.js"></script> 
    <script type="text/javascript"> 
    // A "global" variable that is our XMLHttpRequest object reference. 
    var xmlHttpObj = CreateXmlHttpRequestObject(); 

   
function
LoadCustomers() 
    { 
        if(xmlHttpObj) 
        { 
            // We want this request synchronous 
            xmlHttpObj.open("GET", "./DataFile.xml", false); 

           
// Execute the request
 
            xmlHttpObj.send(null); 

           
// If the request was ok (ie. equal to a Http Status code of 200)
 
            if(xmlHttpObj.status == HTTPSTATUS_OK) 
            { 
                var xmlDoc = xmlHttpObj.responseXML; 
                // Our lists of <CUSTOMER> nodes selected using the X P
ath argument

                var nodes = xmlDoc.selectNodes
("//Customers/Customer/Lastname/text()"
); 

                // Obtain a reference to the <SELECT> drop list control. 
                var ctrl = document.getElementById("ddlCustomers"); 
   
                for (var i=0; i < nodes.length; i++) 
                { 
                    // Get the lastname element from our XML data document 
                    var lastName = nodes[i].nodeValue; 
                    // Create a new <OPTION> node. 
                    var htmlCode = document.createElement('option'); 
                    // Add the new <OPTION> node to our <SELECT> drop
list
                    ctrl.options.add(htmlCode) 
                    // Set the <OPTION> display text and value 
                    htmlCode.text = lastName; 
                    htmlCode.value = lastName;
                }
            }
 
            else 
            { 
                alert("There was a problem accessing the Customer data on the server.!"); 
            } 
        } 
    }


 11 :
동기적 호출을 위해 세번째 인자값으로 false 사용합니다.
 14 :
동기적 호출을 실행합니다. 호출이 종료될 때까지 브라우저는 개속 대기하기에 하얀색 화면을 개속 보여주게 됩니다. 하지만 시간이 그리 길지는 않을 것입니다. 요청 XML 데이터 량이 매우 작기 때문이지요.
 17 :
호출이 성공적으로 이루어지면 xmlHttpObj.status 200 값을 가지게 됩니다. CommonAJAXLibrary.js HTTPSTATUS_OK 변수는 200으로 설정되어 있습니다.
 19 :
호출 결과로 받아온 화일을 통하여 XML 객체를 받아옵니다.
 22 : XML
보면 <Lastname>이라는 테그가 3 있습니다. 3개의 테그가 가지고 있는 값을 배열로 읽어들이겠다는 의미입니다. 오해할 수도 있는데, nodes에는 문자열 배열이 들어갈 같지만 실제로는 node객체의 배열이 저장됩니다. 값을 읽어내는 방법은 30번째 줄에서 확인 있습니다.
 34 : XML
에서 읽어들인 3개의 값을 각각 <select>테그에 추가하고 있습니다. <select> 테그의 항목은 <option> 테그로 만들지요.
 41 : XML
요청시 문제가 발생했다면 출력되게 메세지 입니다. 따라 하는데 메세지가 나올때 만큼 당황스러울 때가 없죠. 부디 메세지를 보지 않고 성공하시기 바랍니다.

 
다음은 DisplayCustomerDetails() 함수입니다. 아래에서는 비동기적 호출이 이루어지므로 위의 동기적 호출과 어떤 차이가 있는지 확인해보시기 바랍니다. 위의 코드에 이어서 작성하시면 됩니다
.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

16

17

18
19
20
21
22
23
24
25
26
 

   
    function DisplayCustomerDetails() 
    { 
        if(xmlHttpObj) 
        { 
            // We want this request asynchronous 
            xmlHttpObj.open("GET", "./DataFile.xml", true); 
   
            xmlHttpObj.onreadystatechange = function() 
            { 
                if(xmlHttpObj.readyState == READYSTATE_COMPLETE) 
                { 
                    var ctrl = document.getElementById("ddlCustomers"); 
                    var doc = xmlHttpObj.responseXML; 
                    var lastName = ctrl.options[ctrl.selectedIndex].value; 
                    var node = doc.selectSingleNode("//Customers/Customer/Lastname='" + lastName + "']"); 
                    var details = 'Fullname: ' + node.selectSingleNode('Firstname/text()').nodeValue + ' ' + lastName +
                                   
'. Email: ' + node.selectSingleNode('email/text()').nodeValue
; 
                    document.getElementById("spnDetailDisplay").childNodes[0].nodeValue = details; 
                } 
            } 
            // Execute the request 
            xmlHttpObj.send(null); 
        } 
    } 
    </script> 


 6 :
세번째 인자가 true이기 때문에 비동기적 호출을 하게됩니다.
 8 :
호출 상태가 변할 마다 호출하게될 함수를 설정합니다.
 10 :
현재 호출 상태가 '완료' 상태인지 확인합니다.
 15 : <select>
테그에서 선택된 항목을 포함하는 노드를 반환합니다.
 23 :
위의 설정 내용을 가지고 호출을 시작합니다. 비동기적 호출이기때문에 함수가 호출되더라도 웹브라우저가 정지하지는 않습니다. 호출이 완료되면 위의 내용대로 <span> 테그에 결과가 출력될 것입니다.

 
지금 작성한 HTML 문서와,  CommonAJAXLibrary.js, DataFile.xml 같은 폴더에 위치시킨 웹브라우저로 HTML문서를 열어보면 다음과 같은 화면을 있습니다
.



 
드롭다운 리스트를 클릭하게 되면 LoadCustomers() 함수가 추가해놓은 3가지 Lastname 값을 확인 있습니다.



 
중에 하나를 선택하면 사람의 Firstname E-mail주소를
DisplayCustomerDetails() 함수가 XML 부터 가져와 화면에 출력하여 줍니다.

Posted by 안혁 windfruit
TAG ajax

Java Script
AJAX
2007. 7. 16.
안혁
http://hyok.kr

.참고문헌
 - Beginning Ajax with ASP.NET <Wrox>


 AJAX라는 것은 기존에 없던 새로운 언어가 아닙니다. "Java Script에서 XML비동기적으로 요청하여 기존 웹프로그래밍의 문제점을 해결한다"라고 하는 기존 기술에 대한 재발견이지요. 이미 AJAX가 이야기 된지도 오래 되었기에, 이미 다들 알고 있는 사실이 아닌가 생각됩니다. 앞에서 이야기한 기술의 핵심인 '' 비동기적 요청이라는 것을 해보도록 하겠습니다.

 Java Script에서 HTTP를 요청하려면 HTTP 객체를 먼저 생성하여야 합니다. 브라우저에 따라 조금 다른데요. 비 MS Explore에서는
    xmlHttpObj =
new XMLHttpRequest();
MS Explore에서는 버전에 따라
    xmlHttpObj =
new ActiveXObject("Microsoft.XMLHTTP");
또는
    xmlHttpObj =
new ActiveXObject("Msxml2.XMLHTTP");
의 방식으로 객체를 생성할 수 있습니다. 이를 코드로 표현하여 본다면
    if(window.XMLHttpRequest)
        xmlHttpObj =
new XMLHttpRequest();
    else
    {
       
try
        {
            xmlHttpObj =
new ActiveXObject("Microsoft.XMLHTTP");
        }
       
catch(e)
        {
            xmlHttpObj =
new ActiveXObject("Msxml2.XMLHTTP");
        }
    }
정도로 표현할 수 있겠습니다. 객체 생성시 마다 매번 이를 기술하는 것보다 함수로 만들어 호출하는 것이 좋으리라 생각됩니다. 저는 다음과 같이 작성하여 이를 CommonAJAXLibrary.js라는 파일로 저장하였습니다. 함수명에 XML글자가 들어있는 것은 이 함수의 주목적이 XML을 다루것에 있기 때문입니다. 꼭 XML만 요청할 수 있어서 그런 것은 아니며 HTML페이지도 요청할 수 있습니다. CreateXmlHttpRequestObject() 함수 위에 존재하는 5개의 변수는 이후에 사용될 상수값입니다. 이에 대해서는 잠시 후 설명드리겠습니다. 여기서는 상수 4만 필요하지만, 코드에 4만 적혀있으면 이해하기 더욱 힘들 것 같아 모두 기록해둡니다. 변수명을 보시면 각각이 무었인지 추측하실 수 있으리라 생각됩니다. 일단 넘어갑시다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26


   
 var READYSTATE_UNINITIALIZED    = 0; 
    var READYSTATE_LOADING          = 1; 
    var READYSTATE_LOADED           = 2; 
    var READYSTATE_INTERACTIVE      = 3; 
    var READYSTATE_COMPLETE        = 4;      

    // XML HTTP Request 객체생성, 반환 
    function CreateXmlHttpRequestObject() 
    { 
        if(window.XMLHttpRequest) 
            xmlHttpObj = new XMLHttpRequest(); // for non-MS browsers 
        else 
        { 
            // for MS browser by version. 
            try 
            { 
                xmlHttpObj = new ActiveXObject("Microsoft.XMLHTTP"); 
            } 
            catch(e) 
           { 
                xmlHttpObj = new ActiveXObject("Msxml2.XMLHTTP"); 
            } 
        } 
     
        return xmlHttpObj; 
    }


 
일단 위의 코드를 CommonAJAXLibrary.js라는 화일로 저장한 다음의 코드를 따라오세요.
 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

17
18
19
20
21
22
 

   
    <script type="text/javascript" src="./CommonAJAXLibrary.js"></script> 
    <script type="text/javascript"> 
    function MakeXMLHttpCall()
    {
        var xmlHttpObj;
        xmlHttpObj = CreateXmlHttpRequestObject();
   
        if(xmlHttpObj)
        {
            var url = "./DataFile.xml";
            xmlHttpObj.open("GET", url, true);
           
xmlHttpObj.onreadystatechange = function()
           { 
                if(xmlHttpObj.readyState == READYSTATE_COMPLETE) 
                { 
                    document.getElementById("divResults").childNodes
[0].nodeValue = xmlHttpObj.responseText; 
                } 
            }
           
xmlHttpObj.send(null); 
        } 
    } 
    </script>


 6 : xmlHttpObj
변수에 방금 만든 함수를 사용하여 XMLHttpRequest객체를 생성합니다.
 10 : url
요청할 페이지의 웹주소를 넣은 11번째 url 줄에서 요청 페이지로 설정합니다.
 11 : xmlHttoObj.open("GET", url, true)
이라하여 요청 URL 설정하는데, 3번째 인자가 false이면 동기식, true이면 비동기식 요청입니다. 동기식으로 요청하면 응답이 있을때까지 대기하며, 비동기식으로 요청하면 응답이 있을때까지 다른 일을 합니다.
 12 : xmlHttpObj.onreadystatechange
이름으로 미루어 보아 요청상태가 변할때 호출하게 함수를 지정하는 것이라 추측 가능하군요. 상태가 변할때마다 호출하는데, 내용을 보면 '완료'상태가 되었을때 xmlHttpObj.responseText 요청한 HTML divResults라는 녀석에게 대입하라는 내용입니다. divResults <div>테그입니다. 오해할만한 것이 있다면, 지금까지는 실행이 아니고 설정이라는 것입니다.
 19 : xmlHttpObj.send(null)
이라는 명령으로 설정에 따라 요청이 시작됩니다. 눈에는 보이지 않지만, 뒤에서 요청이 이루어지고 완료가 되었을때 결과가 <div>테그인 divResults 입력됩니다. 그러면 순간 결과는 화면에 출력되겠지요.

 
다음은 출력을 위한 HTML페이지 입니다. 자바스크립트와 같은 화일에 입력하셨야 합니다.
 


1
2
3
4
5
6
7
8
 

   
<body> 
    <form id="form1" method="post" runat="server"> 
        <input type="button" onclick="MakeXMLHttpCall();" value="Test XMLHTTP  Call" /> 
        <br /> 
        <br /> 
        <div id="divResults">(no results)</div> 
    </form>
</body>


 
위의 자바스크립트와 HTML 화일에 작성하여 마음에 드는 이름으로 저장하십시오. 코드를 그대로 따라오셨다면, 화일과 CommonAJAXLibrary.js 같은 폴더에 있어야 합니다. 다음의 XML코드가 바로 요청대상인 DataFile.xml입니다. 물론 화일도 같은 위치에 있어야 합니다. 내용은  XML 아니어도 됩니다. 일반 HTML 작성해도 되며 텍스트 문서이어도 상관없습니다.
 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
 


<?
xml version="1.0" encoding="utf-8" ?>
<Customers> 
  <Customer> 
    <Firstname>Foe</Firstname> 
    <Lastname>Bloggs</Lastname> 
    <email>joe@bloggs.com</email> 
  </Customer> 
  <Customer> 
    <Firstname>Alen</Firstname> 
    <Lastname>Anonymous</Lastname> 
    <email>anon@ymous.com</email> 
  </Customer>
  <Customer> 
    <Firstname>Marvin</Firstname> 
    <Lastname>Martian</Lastname> 
    <email>marvin@mars.com</email> 
  </Customer>
</Customers>


 HTML
화일을 브라우저로 열면 다음과 같은 화면이 나오게 됩니다.



 
버튼을 누르면 다음과 같이 요청된 페이지가 출력됩니다.

Posted by 안혁 windfruit
TAG ajax
이전버튼 1 이전버튼