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