출처: 마이크로소프트웨어 7월 기사
 

웹 애플리케이션 개발자들에게 있어 데스크탑 애플리케이션에서나 볼 수 있는 풍부한 인터페이스는 항상 부러움의 대상이다. 액티브X, 플래시, 자바 애플릿 등을 이용하여 HTTP와 HTML의 한계를 넘어선 유저 인터페이스를 구현할 수 있지만 플랫폼의 제한, 플러그인 형식으로 인한 설치문제 등이 있다. 하지만 여기서 소개할 AJAX는 전혀 새로운 기술이 아닌 지금까지 웹에서 널리 쓰여 왔던 자바스크립트, DHTML 등의 기존 기술들을 모아 풍부한 유저 인터페이스를 구현할 수 있도록 정립한 기술 집합체로 최근 관심이 모아지고 있다.

HTTP는 네트워크에서 발생하는 모든 웹 요청과 응답을 처리할 수 있는 웹 표준 프로토콜로 완전히 자리 잡았다. 하지만 HTTP는 비연결성 프로토콜로 기본적으로 요청과 요청 사이에 연관성이 없고 웹 서버에 보낸 요청에 대한 응답에 대해서 각각의 웹 문서를 매번 다시 렌더링하여 리프레시해야 하는 단점이 있다. 로딩이 끝나 렌더링이 끝난 웹 페이지를 DHTML을 이용하여 동적으로 레이아웃이나 스타일을 재구성할 수도 있지만 재구성에 필요한 데이터는 사용자의 입력 또는 페이지를 로딩할 당시 서버에서 모든 데이터를 미리 읽어와야만 한다. 하지만 사용자가 어떤 데이터를 입력할지 모르는 상황이고 그렇다고 해서 모든 경우의 수에 해당하는 데이터를 브라우저로 로딩시킬 수도 없다.
결국 웹 애플리케이션이 클라이언트와 상호작용하기 위해서는 웹 서버와의 통신이 불가피하고 웹 서버와의 통신은 매번 웹 페이지가 새롭게 리프레시된다는 것을 의미한다. 클라이언트와의 상호작용 하나 하나에 대해 웹 페이지가 매번 리프레시된다는 것은 응답성(responsiveness), 사용성(usability)의 저하를 의미한다. 웹 애플리케이션 개발자의 입장에서는 로컬PC에서 작동하는 데스크탑 애플리케이션의 빠른 응답성과 편리한 사용성이 부럽지 않을 수가 없다. 이러한 핸디캡을 극복하기 위해 이미 웹에서는 액티브X, 자바 애플릿, 플래시 등의 기술이 사용되고 있다. 이들 기술들은 간단한 브라우저 플러그인으로 작동하며 HTML만으로는 구현할 수 없는 인터랙티브한 웹 페이지를 표현할 수 있도록 해주어 데스크탑 애플리케이션 못지않은 사용성과 응답성을 보여준다.
최근 들어 이러한 플러그인들의 도움없이 브라우저 자체만 가지고 인터랙티브하고 응답성, 사용성을 높일 수 있는 AJAX(Asynchro nous Javascript + XML)가 주목을 받고 있다.

이미 AJAX는 구글 맵(http://maps.google.com), Orkut(http://www.orkut.com), Google Suggest(http://www.google.com/webhp?complete =1&hl=en), Gmail(http://www.gmail.com), A9(http:// a9.com), Flickr(http://www.flickr.com) 등에서 선보인 바 있으며 AJAX를 사용하고 있는 웹 사이트가 늘어나고 있는 추세이다.
구글 맵에서는 웹 페이지를 스크롤하거나 확대, 축소를 하게 되면 현재 페이지에 없는 부분의 지도 이미지를 페이지 리로딩없이 읽어서 변화된 부분만 채워준다. Orkut에서는 친구들에 대한 평점을 하트, 또는 별, 얼음의 개수로 표현할 수 있는데, 클릭하는 즉시 페이지 리로딩없이 바로 친구들에 대한 평점이 반영된다. Gmail에서는 메일에 별마크 붙이기를 해보면 페이지를 리로딩하지 않고 별을 붙이거나 없애거나 할 수 있고, 메일을 보낼 때 주소록에 등록된 사람의 이름 또는 주소로 데스크탑 웹메일 클라이언트에서나 볼 수 있는 자동 완성도 볼 수 있다. Flickr에서는 그림 제목이나 설명 부분을 클릭하면 바로 편집상태로 변화되고 새로운 제목이나 설명을 입력하고 저장 버튼을 누르면 바로 변경이 된다. 이 모든 게 웹페이지 전체를 리로딩하지 않고 일부만을 비동기적으로 변화시키는 AJAX를 이용한 것이다.

 


AJAX란?

AJAX는 독립적이고 구체적인 하나의 특정 기술을 지칭하는 것이 아니다. 웹에 이미 존재하고 있는 DHTML, CSS, XML, XMLHttpRequest등의 기술들을 합친 새로운 기술 또는 그 기술들을 이용하여 보여줄 수 있는 이용형태를 나타낸다.

 AJAX의 핵심을 이루는 XMLHttpRequest는 인터넷 익스플로러(이하 IE)5.0에서부터 이미 액티브X오브젝트 형태로 제공되기 시작했고 그 후 모질라(Mozilla) 1.0에서부터 윈도우 오브젝트 형태로 XMLHttpRequest 객체가 지원되기 시작하였다. 그 이외에 넷스케이프 7, 맥의 사파리(Safari) 1.2, 오페라(Opera) 7.6에서부터, 그리고 모든 파이어폭스(firefox) 버전에서 지원하고 있다. XMLHttpRequest가 IE에서 액트브X 오브젝트로 다루고 있기 때문에 IE와 다른 브라우저들 간의 XMLHttpRequest 객체를 가져오는 방법이 다르고 브라우저 간에 인터페이스나 구현의 차이로 인해 미묘한 차이점을 보이는 문제가 아직 존재한다. 

 

AJAX를 사용하는 목적

AJAX를 사용하는 가장 큰 이유는 웹에서 액티브X, 플래시 또는 자바 애플릿 등에 의존했던 사용성, 접근성, 응답성의 향상이다. 네트워크 인프라가 발전하여 네트워크 속도가 아무리 발라진다고 하더라도 새로운 컨텐츠를 보여주기 위해서 웹 페이지 전체가 매번 리로딩되는 것은 사용성, 응답성의 한계로 이어질 수밖에는 없다. 웹 페이지의 전체 레이아웃이 바뀐다면 웹페이지 전체가 다시 그려지는 것이 불가피 하겠지만(사실 DOM 인터페이스를 이용하여 HTML문서의 전체 구조를 바꿈으로서 레이아웃을 변경할 수는 있지만 효용성은 없을 것이다), 일부 레이아웃 변경 또는 레이아웃은 유지한 채 내용만 변경되는 것이라면 웹 페이지  전부를 다시 리로딩한다는 것이 불필요하게 느껴질 수 있다. 또 모든 액션이 요청을 보내고 응답이 오기를 기다리고 응담이 온 후에 다른 액션 또는 요청을 보내는 동기적인 사용 행태도 기존 웹 어플리게이션의 한계로 느껴질 수 있다.

 

AJAX는 무엇이 다른가?

AJAX의 초점은 앞에서 안급한 기존 웹 어플리케이션의 비효율성, 동기적인 액선의 단점을 해결할 수 있는 웹 페이지의 부분적인 변화, 적용과 비동기성에 있다. 하지만 굳이 AJAX만이 대안은 아니다. 액티브X, 자바 애플릿, 플래시 등이 그 대안이 될 수 있다. 하지만 그러한 기술들 대신에 AJAX가 가질 수 있는 경쟁력을 얘기하자면 플러그인을 사용하지 않고 브라우저만으로 바로 이용할 수 있다는 것과 새로운 것을 배우지 않고 DHTML, 자바스크립트, CSS등의 기존 웹 기술들을 그대로 이용할 수 있다는 것이다. 이러한 장점들은 지금도 널리 사용되고 있는 액티브X, 자바 애플릿, 플래시 등의 기술에 대한 대안으로 AJAX에 관심을 가져볼만한 충분한 이유를 준다.

 

AJAX 어플리케이션 이용 행태

기존 웹 애플리케이션 이용 행태에서는 사용자가 서버 측에 요청을 보내면 서버에서 응답이 클라이언트로 모두 전송되고 관련 리소스가 모두 로딩된 이후에 또 다른 행동을 취할 수가 있었다.

 하지만 AJAX 어플리케이션에서는 서버 측에 보내는 요청이 비동기적으로 이루어지기 때문에 요청을 보낸 이후에도 응답이 완료되기를 기다리지 않고 또 다른 요청을 보내거나 그 이외에 액션을 취할 수 있다.

 

AJAX의 구성 요소들

XMLHttpRequest

XMLHttpRequest는 웹 서버와 통신하기 위한 AJAX의 핵심 컴포넌트이다. 이미 IE에서는 5.0에서부터 액트브X 오브젝트 형태로 제공되고 있고 그 이외의 브라우저에서는 XMLHttpRequest라는 윈도우 객체에 속해 있는 객체의 형태로 제공된다. AJAX를 이용하여 스크립트를 작성할 때 가장 큰 차이를 보이는 부분이 XMLHttpRequest 객체를 가져오는 부분인데, 브라우저에 따라 차이를 보인다. 최근에 발표된 오페라 8.0에서 Gmail을 지원한다고 프로모션 하고 있는데, 이는 Gmail에서 AJAX를 사용할 수 있도록 XMLHttpRequest를 지원하기 시작했다는 의미이다.



 XMLHttpRequest는 아직 W3C(
http://www.w3c.org) 표준이 아니지만 W3C에는 XMLHttpRequest와 비슷한 DOM Level 3의 Load and Save specification이 있다. 아직 DOM Level3의 Load and Save가 구현된 브라우저는 없지만 다이나믹하게 XML문서를 읽어내서 DOM에 적용하고 DOM구조를 XML로 serialize한다는 개념은 다소 비슷한 부분이 있다.

 

XMLHttpRequest 객체 얻어오기

XMLHttpRequest를 얻어오는 방법은 IE와 그 이외의 브라우저가 서로 다르다.

 

* 인터넷 익스플로러

var xmlhttp = new ActiveXObject("Microsoft.XMLHTTP")

 

* 그 이외의 브라우저

 var xmlhttp = new XMLHttpRequest()

 

 좀 더 일반적인 방법으로는 다음과 같이 XMLHttpRequest 객체를 얻어올 수 있다.

 var xmlhttp = false

 if(window.XMLHttpRequest){

   xmlhttp = new XMLHttpRequest()

 } else {

   xmlhttp = new ActiveXObject("Microsoft.XMLHTTP")

 }

 

XMLHttpRequest의 이용

AJAX에 있어서 가장 매력적인 부분은 비동기성이다. XMLHttpRequest는 동기적, 비동기적 등 두가지 방법으로 이용할 수 있는데, AJAX에서는 비동기적인 방법을 주로 이용하게 된다. 비동기 모드로 XMLHttpRequest를 사용할 경우 send()가 호출된 후 웹 서버로부터 응답이 오기를 기다리며 브라우저가 멈춰있지 않고 웹 서버로부터 결과를 모두 받아낸 이후 콜백 핸들러에 정의된 코드가 실행되기 때문에 사용자는 계속 브라우저를 이용할 수 있게 된다.

 

 * XMLHttpRequest의 동기적 이용 예제

 xmlhttp.open("GET", "test.html", false);

 xmlhttp.send(null);

 if (xmlhttp.status == 200){

      alert(xmlhttp.responseText);

 }

 

 * XMLHttpRequest의 비동기적 이용 예제

 xmlhttp.open("GET", "test.html", true);

 xmlhttp.onreadystatechange = function() {

    if (xmlhttp.readyState == 4) {

       if (xmlhttp.status == 200) {

            alert(xmlhttp.responseText);

       }

     }

    }

  xmlhttp.send(null);

 

 XMLHttpRequest를 동기적으로 이용할 때에는 XMLHttpRequest의 send()를 호출한 뒤 response의 status code를 체크하고 responseText에서 결과를 꺼내오면 되므로 자바에서 java.net.HttpURLConnection을 사용하는 방식과 비슷하다. 동기적으로 XMLHttpRequest를 이용할 때는 XMLHttpRequest의 open() 메쏘드의 3번째 파라메터 값을 false로 줘야 한다. open()의 3번째 파라메터는 비동기적으로 이용할 것인지를 나타내는 boolean 값이 들어가고 default로 true이며 생략 가능하다.

 XMLHttpRequest를 비동기적으로 이용할 때에는 send()를 호출하기 전에 XMLHttpRequest의 onreadystatechange 프로퍼티에 XMLHttpRequest의 상태가 변할 때마다 실행될 핸들러를 function reference 형태로 줘야 한다. XMLHttpRequest의 상태는 <표 2>와 같이 5개의 상태를 가지지만 보통 가장 마지막 상태인 완료 상태를 체크해서 처리해주면 된다.

 

보안 이슈

XMLHttpRequest에서의 보안은 자바 애플릿이나 자바스크립트에서 흔히 사용하는 HTML 문서의 도메인(domain)을 이용한 보안 방법과 같다. 즉 XMLHttpRequest가 작동하는 HTML문서는 해당 문서의 doc-ument object의 도메인 프로퍼티와 같은 도메인의 서버에만 요청을 보낼 수 있다.

 

DOM

웹 페이지를 동적으로 재구성하기 위해서 빼놓을 수 없는 것이 DOM(null Object Model)이다. DOM은 일반적인 문서 구조를 플랫폼·언어 독립적으로 접근할 수 있는 인터페이스를 제공하는데, XML 문서를 구조적으로 분석하기 위해서 주로 사용된다. 거의 모든 브라우저가 DOM을 지원하기 때문에 HTML의 각 요소를 DOM인터페이스를 이용하여 접근할 수 있고 변경할 수 있다. HTML 태그로 표현되는 각 요소들, 즉 DOM 객체들을 변경할 수 있다는 얘기와 같다. 때문에 DOM은 DHTML에서 빼놓을 수 없는 요소이고 AJAX에서 서버와 통신한 결과를 반영하기 위해 필요하다.

 

DHTML

AJAX에서 서버와 통신한 결과를 화면에 다이나믹하게 적용하기 위해서 여러 가지 방법이 사용된다. 그 중 전통적이고 쉽게 이용할 수 있는 방법이 DHTML을 이용하는 방법이다. DHTML은 CSS, 자바스크립트, DOM 등을 이용해 HTML 문서의 레이아웃, 스타일, 컨텐츠를 바꿀 수 있는 기술이므로 AJAX를 이용해서 얻어낸 새로운 결과를 HTML문서에 적용시키지 알맞다.

 

XMLHttpRequest를 이용해 받은 결과 화면에 적용하기

XMLHttpRequest를 이용해서 서버와 통신 후 결과는 XMLHttpRequest의 responseHTML 프로퍼티에 저장된다. 통신 결과가 평범한 HTML이고 이 결과를 화면에 바로 적용하는 것이라면 DOM인터페이스를 사용하여 적용하고 싶은 HTML 요소를 찾은 뒤 innerHTML 프로퍼티 responseHTML의 값을 복사해주는 방식으로 결과를 적용하면 된다. 다음 예제 코드는 HTML 결과물(responseText)을 ID가 "result"인 HTML 요소에 적용하는 것이다.

...

xmlhttp.onreadystatechange = function() {

  if (xmlhttp.readyState == 4) {

     if (xmlhttp.status == 200){

        doc-ument.getElementById("result").innerHTML = xmlhttp.responseText;

     }

  }

 }

 xmlhttp.send(null);

...

 

XML.XSLT

XML은 서버와 데이터를 주고받기 위해 사용되고 XSLT는 서버로부터 받은 데이터를 HTML로 변환하기 위해 사용된다. XML 형태로 받은 데이터를 XSLT를 이용해 HTML로 변환한 뒤 그 결과를 원하는 위치에 삽입해 반영할 수 있다. XMLHttpRequest를 이용해서 웹 서버와의 통신 결과를 responseText로 받을 수도 있고 responseXML로 받을 수도 있다. responseText는 웹 서버와의 통신 결과를 문자열 그대로 저장하고 있지만 responseXML은 응답이 XML 문서인 경우에만 파싱하여 DOM의 XMLnull 객체로 가지고 있게 된다. 응답이 XML인지는 응답 헤더인 Content-Type이 text/xml인지 아닌지로 판단하고, 유효한 XML이 아닌 경우에는 XMLnull 객체의 프로퍼티나 메쏘드에 접근할 때 parse error를 낸다.

 

자바스크립트

자바스크립트는 앞에 제시된 모든 기술들을 사용하기 위한 프로그래밍 언어로 사용된다. 브라우저에서 사용되는 스크립트 언어라면 무엇이든 상관없다. IE에서만 작동하게 하려면 vbscript를 대신 사용해도 좋다. 서버와 통신을 위해 생성한 XMLHttpRequest 객체를 이용해서 통신하고 DOM 인터페이스를 이용하여 현재 페이지를 재구성 할 수 있도록 하는 역할을 한다.

 

AJAX 엔진

AJAX는 구체적이고 독립적인 기술이 아니고 여러 웹 관련 기술들을 통합적으로 이용하는 아키텍처 또는 스타일이고 아직 구체적인 스펙이 정해진 것은 아니다. AJAX는 XMLHttpRequest를 이용하여 서버와 비동기적인 통신을 하고 그 결과를 다이나믹하게 화면에 반영시켜주는 것이지만 아직은 이와 같은 어플리케이션을 손수 모두 제작해야한다. AJAX 엔진이란 이와 같은 AJAX의 행태를 구체화시킨 것으로 보통 다음과 같은 역할을 하는 자바스크립트 라이브러리를 말한다.

 

웹 서버와 데이터 호환성 제공

일반 HTML이 아닌 HTML에 반영되기 위한 데이터가 AJAX를 이용한 웹 서버와의 통신 내용이 된다. 때문에 웹 서버 애플리케이션에서 사용하는 데이터 타입과 브라우저에서 스크립트가 사용하기 위한 데이터 타입이 통일되어야할 필요가 있는데 XML이나 JSON(http://www.json.org) 또는 DWR(http://www.getahead.ltd.uk/dwr/)등을 사용할 수 있다.

 

XMLHttpRequest를 사용하기 위한 통일된 인터페이스 제공

XMLHttpRequest가 브라우저에 따라 정체성도 다르고 스펙 또한 W3C의 표준이 아닌 상태이다. 때문에 XMLHttpRequest를 다루기 위한 통일된 인터페이스가 필요하다.

 

사용자 입력 및 웹 서버와의 통신 결과 반영

현재 페이지를 유지한 상태에서 사용자 입력에 대한 결과를 반영하려면 DHTML을 이용해 반영하면 되지만 브라우저에 따라 조금씩 다른 DOM 객체 이용법과 그것들을 적용하기 위한 수많은 자바스크립트 코드를 생각하면 통일성 있게 제공해주는 라이브러리가 필요할 것이다.

 

AJAX by example

iframe을 이용하지 않고 input form을 통해서 외부 HTML 문서의 이름을 입력받아서 해당 HTML 문서를 화면의 일부에 포함시키는 예제를 생각해보자. 화면의 레이아웃은 <그림 4>와 같다.

 ajax_exam.html은 AJAX를 이용하여 외부 HTML 파일을 현재 HTML문서에 포함시킬 수 있는 스크립트를 포함하고 있다. 예제로 first.html과 second.html이 있는데 각각 다른 문자열을 가지고 있는 평범한 텍스트 파일이다. 폼의 input 영역에 파일 이름을 입력하게 되면 폼의 onsubmit 이벤트를 받아 include() 함수를 호출하게 된다. include() 함수가 실행되는 주요 흐름은 <표3>과 같다.

 include 함수는 무조건 false를 반환하므로 include() 함수가 실행될 뿐 폼이 서버에 전달되지는 않는다. 때문에 현재 HTML페이지는 리플레시되지 않고 현재 상태를 계속 유지한 체 HTTP 요청을 보내 특정 부분만을 변화시킬 수 있는 것이다.

 

<script language="javascript">

  function getXmlHttpRequest() {

     var xmlhttp = false;

     

     if (window.XMLHttpRequest) {

        xmlhttp = new XMLHttpRequest();

     } else {

        xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");

     }

     return xmlhttp;

  }
  function include() {

     var xmlhttp = getXmlHttpRequest();

     var url = doc-ument.ajax_form.url.value;

     if (url) {

        var originalMessage = doc-ument.getElementById("result").innerHTML;

        doc-ument.getElementById("result").innerHTML = "Loading";

        xmlhttp.open("GET", url, true);

        xmlhttp.onreadystatechange = function() {

           if (xmlhttp.readyState == 4) {

              if (xmlhttp.status == 200) {

                 doc-ument.getElementById("result").innerHTML = xmlhttp.responseText;

              } else {

                 alert("Error while loading " + url + ",("

                            + xmlhttp.status + " " + xmlhttp.statusText + ")");

                 doc-ument.getElementById("result").innerHTML = originalMessage;

               }

            }

          }

          xmlhttp.send(null);

       }

       return false;

    }

 </script>

 <form name="ajax_form" on-submit="return include();">

     <input type="text" name="url" size="50">

     <input type="submit" value="include">

     <input type="reset" value="clear">

  </form>

  <fieldset>

      <legend>Result</legend>

      <div id="result" style="height:20px;">

            Included here.

       </div>

   </fieldset>

 

변화의 여지는 많다

AJAX가 기존 기술들의 응용만으로 웹 어플리케이션에 풍부한 유저 인터페이스를 제공하는데 비해 견고하게 정립된 독립적인 기술이 아니고 XMLHttpRequest를 중심으로 한 여러 기술들을 이용하는 행태이고 확실한 표준이 아니기 때문에 변화의 여지는 많다. 또 손쉽게 구현할 수 있어서 지나치게 사용할 우려가 있으므로 신중하게 필요한 곳에 사용해야 한다. 다음 시간에는 AJAX를 이용하여 서버와 통신하는 구체적인 방법을 알아보고 관련된 프로토콜, 라이브러리를 소개하고자 한다. 끝

 


 

 
블로그 이미지

시반

시반(詩伴)이란 함께 시를 짓는 벗이란 뜻을 가지고 있습니다. 함께 나눌수 있는 그런 공간이길 바라며...

카테고리

분류 전체보기 (233)
개발 이야기 (73)
WEB2.0 (57)
DB2 (24)
MySQL (6)
오라클 (26)
기타 (44)
취미 (0)
잡담 (2)