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로 부터 가져와 화면에 출력하여 줍니다.