본문 바로가기

.주제별

[Book] Ajax in Action

[알림] 이 글은 "에이콘 출판사" 의 "Ajax in Action" 번역판을 요약한 것입니다.
=====================================
## First Step Ajax

1. Ajax의 기본 구성 요소
    Ajax는 4가지의 기술을 모아 사용한다. 다음은 Ajax의 기본 구성요소를 보여준다.
    

 

 

 

 

DHTML

자바스크립트

자바스크립트는 애플리케이션 프로그램에 내장해 사용하기 좋은 범용 Scripting 언어이다. 웹 브라우저에 내장된 자바스크립트를 활용해 프로그램을 작성하면 브라우저가 제공하는 여러 기능을 직접 제어할 수 있다. Ajax 애플리케이션도 모두 자바 스크립트로 작성한다.

CSS

CSS를 활용하면, 화면 표시 스타일을 재사용 가능하도록 모듈화할 수 있는데, 다시 말하면 화면 표시 형식을 간단하면서도 강력한 방법으로 한꺼번에 조절할 수 있다. Ajax 애플리케이션은 흔히 CSS로 사용자 인터페이스의 스타일을 조절한다

OM

웹 페이지의 상세한 모든 구조를 객체로 표현해 자바스크립트로 직접 프로그래밍 할 수 있다. 자바스크립트로 DOM을 제어하면 페이지를 새로고침 하는 대신 사용자 인터페이스를 동적으로 변경할 수 있다.

XMLHttpRequest 객체

백그라운도로 웹 서버에 요청을 보내고 결과를 얻어올 수 있다.

 

    다음은, 이 4가지 주요요소간의 관계를 표현한 그림이다.

사용자 삽입 이미지





























2. JavaScript로 만드는 새로운 사용자 인터페이스
    Ajax 애플리케이션은 '데이터와 화면'과 '비지니스 로직'을 묶어 소프트웨어의 클라이언트 부분을
    웹 브라우저의 메모리에 다운로는 받는데, 이런 부분을 구현하는 것이 "JavaScript" 이다.
   
    인터프리트해 실행하는 범용 스크립트 언어이다.
       - 인터프리트 : 실행 코드로 컴파일 하지 않고, 소스코드를 직접 실행한다
                즉, 자바스크립트로 프로그램을 만들어 웹서버에 놓아두면, 해당 자바스크립 소스 코드가
                직접 웹브라우저로 전송된다.

    [note] Ajax의 4가지 기술을 통합하는 것은 바로 자바스크립트이다.

3. CSS (Cascading Style Sheet)로 화면 모양 만들기
    색상, 테두리, 배경이미지, 투명도, 크기 등은 물론이고,
    각각의 웹 페이지 구성 요소가 상대적으로 어떻게 배치되고
    사용자의 움직임에 반응하는지를 정의 할수 있다.

    CSS 스타일에는 두 스타일 규칙이 있다.

    1) CSS Selector
          어떤 구성요소에 스타일을 적용할지를 명시한다.
         
h1 { color : red}   // 해당 문서에 들어있는 모든 <h1> 태그로 지정된 곳을 붉은색으로 표시함

          다양한 셀렉터 지정 방법을 알아보자

          가. 엘리먼트 기반의 셀렉터
div h1  { color : red}   // <div> 태그 안에 포한된 <h1> 태그로 한정

          나. 스타일을 적용할 클래스를 정의
             callout 클래스를 만들어서, 색깔있는 사각형 상자안에 표시하도록 정의함.
             - 스타일 선언
.callout { border: solid blue 1px; backgroud-color: cyan}

             - 엘리먼트에 적용
<div> 일반적인 테스트 스타일 </div>
<div class='callout'> callout을 지정한 스타일 </div>

          다. 스타일을 적용할 클래스를 정의 (클래스 2개 사용)
             위 callout 클래스에 이어서, loud라는 클래스를 정의해보자..
             - 스타일 선언
.loud { color: orange}

             - 엘리먼트에 적용
<div class='loud'> 밝은 오렌지색 텍스트 </div>
<div class='callout'> callout을 지정한 스타일 </div>
<div class='callout loud'> loud와 callout을 섞은 스타일 </div>

       자세한 사항은 CSS의 권고안(W3C)을 참조

    2) Style declaration
          HTML의 모든 엘리먼트는 다양한 방법으로 스타일을 지정할 수 있다.

       가. 엘리먼트의 텍스트 스타일 지정하기
             - 여러개의 글꼴 이름을 순서대로 지정. 특정 문단의 텍스트를 회색처리
.robotic {
    font-size: 14pt;
    font-family: courier new, courier, monospace;
    font-weight: bold;
    color: gray;
}

             - 위를 간단하게 표시
.robotic {
   font-: bold 14pt courier new, courier, monospace;
    color: gray;
}

      나. 박스모델 정의
.padded{ padding: 4px;}
.ecentricPadded {
       padding-bottom: 8px;
       padding-top: 2px;
       padding-left: 2px;
       padding-right: 16px;
       margin: 1px;
}

      다. 배경 색상 지정하기

.titlebar { background-image: url(images/topbar.png); }

       자세한 사항은 CSS의 권고안(W3C)을 참조

    3) 간단한 CSS 예제

4. DOM (Document Object Model) 기반 화면 구성
    자바스크립트는 DOM으로 웹 페이지 구성 요소를 직접 활용할 수 있다.
    W3C의 DOM 소개 참조

    1) 자바스크립트로 DOM 다루는 법 (예제)
          DOM의 내용을 변경하는 데 가장 간편한 방법 중에 하나는 "웹브라우저에 HTML을 직접 전달"
          하는 방법이다.

          가. 기본 HTML 페이지

 Ajax "hello" 페이지

<html>
<head>
<link rel='stylesheet' type='text/css' href='hello.css' />
/* 스타일 시트 파일 참조 */
<script type='text/javascript' src='hello.js'> </script> /* 자바스크립트 파일 참조 */
</head>

<body>
<p id='hello'>
<div id='empty'></div>  /* 내용이 없는 <div> 엘리먼트 */ㅊ
</body>


          나. 스타일 지정

hello.css

.declared{
        color: red;
        font-family: arial;
        font-weight: normal;
        font-size: 16px;
}

.programmed{
        color: blue;
        font-family: helvetica;
        font-weight: bold;
        font-size: 10px;
}


          다. 자바스크립트
            여러가지 DOM처리 메소드를 사용해 DOM 노드의 속성을 변경하거나,
             노드를 표시하거나 숨기고, 새로운 노드를 즉시 만들어 내는 등의작업을 실행한다.

hello.js

//프로그램의 시작점, 웹페이지가 문서를 모두 다운로드 했을때,
//window.onload()가 자동으로 호출됨.
window.onload = function()
{
        var hello=document.getElementById('hello');
        hello.className='declared';

        var empty=document.getElementById('empty');
        addNode(empty,"reader of");
        addNode(empty,"Ajax in Action!");

        var children=empty.childNodes;
        for (var i=0; i<children.length;i++)
        {
                children[i].className='programmed';
        }

        empty.style.border='solid green 2px';
        empty.style.width="200px";
}

function addNode(el, text)
{
        var childEl = document.createElement("div"):
        el.appendChild(childEl);
        var txtNode = document.createTextNode(text);
        childEl.appendChild(txtNode);

}


   2) DOM 노드 찾기
       자바스크립트로 DOM을 활용하고자 할 때, 가장 먼저 DOM 계층 구조의 엘리먼트 가운데 변경할
       엘리먼트을 찾아내는 일이다.
       특정 엘리먼트에 유일한 ID을 부녀함으로써, 노드를 찾을 수 있다.

       가. ID지정과 이를 통해서 노드 찾기 (예제)
           - ID 지정
<p id = 'hello>
<div id = 'empty'> </div>

           - 노드 찾기
var hello = document.getElementById('hello');

      나. DOM 계층 구조를 차례대로 찾아가기
          DOM노드는 하나의 상위 노드와 여러개의 하위 노드를 갖는다.
          각각 'parentNode' 와 'childNodes' 속성으로 따라갈 수 있다.

var children = empty.childNodes;
for (var i = 0; i<children.length; i++)
{
    ....
}

       다. ID 지정 하지 않은, 태그를 직접 찾아내기
         'getElementsByTagName()' 메소르를 사용하여, DOM게층 구조를 검색할 수 있다.
          e.g. document.getElementsByTagName("UL")
                해당 무넛의 모든 "<UL>" 태그의 객체를 배열로 알려준다.

   3) DOM 노드 생성
       새로운 노드를 만들어 문서에 추가한다.
       메소드 : document.createElement() 와 document.createTextnode()

       가. 노드 만들기
           - 태그 유형을 지정해서, 어떤 형태의 HTML 태그를 만들어 낸다.
var childE1 = document.createElement("div");

           - 테그스 노드를 만들어 낸다.
              제목, div, 문단, 목록 등의 안에 나타나는 텍스트 노드를 만들어 준다.
var txtNode = document.createTextNode("some text);

       나. 문서에 노드를 붙이기
            노드를 생성한 후, 웹 브라우저 화면에 나타나게 하려면 문서에 붙여야 한다.
          메소드 : appenChild()
el.appenChild(childEl);

  4) 스타일 적용
       웹브라우저는 자바스크립트와 연동하여, 각 속성의 값을 입력해가며 화면에 어떻게 나타나는지를
       직접 확인하거나, CSS클래스를 써서 스타일을 일률적으로 적용하는 방법을 사용한다.

       가. 'className' 속성
             이를 사용하여, 문서의 원하는 부분에 스타일시트에 미리 정의해둔 스타일 규칙을 한번에 적용
             할 수 있다.
           -  'hello' 는 DOM 노드이고, 이 노드에 스타일 "declared'에 정의해둔 모양으로 지정함
hello.className = 'declared'

       나. 'style' 속성
          스타일 적용(위) 이후, 특정 엘리먼트의 스타일만 수정할 수가 있다.
           -  empty노드에 스타일 적용 후, 다음처럼 주변에 테두리
empty.style.border = "solid green 2px";
empty.style.width = "200px"

   5) inner HTML속성 활용
       웹 브라우저는 'innerHTML'속성을 통해서, 각기 다른 내용을 해당 엘리먼트에 간편하게
       지정할 수가 있다.

       - addNoe() 함수를 innerHTML을 사용해서 수정해보자
function addListItemUsingInnerHTML(el, text) {
    el.innerHTML += "<div class='programmed'>"+text+"</div>";
}

5. XML 데이터를 비동기적으로 읽어오기
    사용자 입장에서 서버에 보낸 요청에 대한 응답을 비동기적으로 처리함.

사용자 삽입 이미지


















    1) IFrame

    2) XmlDocument와 XMLHttpRequest
       - XmlDocument와 XMLHttpRequest는 표준에 정의된 객체는 아님
       - 백그라운드로 비동기적으로 데이터를 읽어오는 데 적합함
        가. XmlHttpRequest 예제

getXMLHTTPRequest() 함수

function getXMLHTTPRequest()
{
  var xRequest=null;
  if (window.XMLHttpRequest)
  {
    xRequest = new XMLHttpRequest();  //모질라/ 사파리
  }else if (typeof ActiveXObject != "undefined")
  {
    xRequest = new ActiveXobject
        ("Microsoft.XMLHTTP");  //인터넷 익스플로러
  }
  return xRequest;
}

       나. 서버에 요청보내기
          XMLHttpRequest 객체로 서버에 요청을 보낼때는,
          얻고자 하는 데이터를 만들어 줄 "웹페이지의 URL"을 넘겨주면 된다.

서버에 요청 보내기

function sendRequest(url, params, HttpMethod)
{
    if (!HttpMethod)
    {
        HttpMethod = "POST";
    }
    var req = getXMLHTTPRequest();
    
    if (req)
    {
        req.open(HttpMethod, url, true);
        req.setRequestHeader
            ("Content-Type,
             "application/x-www-form-urlencoded);
        req.send(params);
    }
}

    3) 요청 결과를 받기 위한 콜백 함수
콜백 함수 사용하기
var READY_STATE_UNINTIALIZED=0;
var READY_STATE_LOADING=1;
var READY_STATE_LOADED=2;
var READY_STATE_INTERACTIVE=3;
var READY_STATE_COMPLETE=4;
var req;

function sendRequest(url, params, HttpMethod)
{
    if (!HttpMethod)
    {
        HttpMethod = "GET";
    }
    var req = getXMLHTTPRequest();
   
    if (req)
    {
        req.onreadystatechange = onReadyStateChange;
        req.open(HttpMethod, url, true);
        req.setRequestHeader
            ("Content-Type,
             "application/x-www-form-urlencoded);
        req.send(params);
    }
}

function onReadyStateChange()
{
    var ready = req.readyState;
    var data = null;
    if (ready == READY_STATE_COMPLETE)
    {
        data = req.responseText;
    } else
    {
        data = "loading...["+ready+"];
    }
    //..받아온 자료를 사용한다.
}

    4) 전체 과정
       전체과정으로는 다음과 같다.
       - XMLHTtpRequest 객체 생성
       - 객체가 문서를 다운로드 받도록 요청
       - 콜백 함수를 통해 문서를 비동기적으로 받아옴

XMLHttpRequest 로 문서를 받아오는 전체과정
<html>
<head>
<script type='text/javascript'>

<script type='text/javascript'>

var req=null;
var console=null;
var READY_STATE_UNINITIALIZED=0;
var READY_STATE_LOADING=1;
var READY_STATE_LOADED=2;
var READY_STATE_INTERACTIVE=3;
var READY_STATE_COMPLETE=4;

function sendRequest(url, params, HttpMethod)
{
    if(!HttpMethod)
    {
        HttpMethod = "GET";
    }
   
    req = initXMLHTTPRequest();
   
    if (req)
    {
        req.onreadystatechange = onReadyState;
        req.open(HttpMethod, url, true);
        req.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
        req.send(params);
    }
}

function initXMLHTTPRequest()
{
    var xReqeust = null;
    if (window.XMLHttpRequest)
    {
        xRequest = new XMLHttpRequest();
    }else if(window.ActiveXObject)
    {
        xRequest = new ActiveXObject("Microsoft.XMLHTTP");
    }
    return xRequest;
}

function onReadyState()
{
    var ready=req.readyState;
    var data=null;
    if (ready == READY_STATE_COMPLETE)
    {
        data=req.responseText;
    } else
    {
        data="loading...["+ready+"]";
    }
    toConsole(data);
}

function toConsole(data)
{
    if (console!=null)
    {
        var newline = document.createElement("div");
        console.appendChild(newline);
        var txt=document.createTextNode(data);
        newline.appendChild(txt);
    }
}

window.onload=function()
{
    console = document.getElementById('console');
    sendReqeuest("data.txt");
}

</script>
</head>
<body>
<div id = 'console'> </div>
</body>
</html>


    이 결과가 궁금한 사람을 다음 링크를 누르기 바란다.
    (실제로 위 코드는 오류가 있는듯 하다. 아직 모른다.;; 왜 그런지 오타일까? ㅠ.ㅠ)

     MS에서 실행한 화면은 다음과 같다.

loading...[1]
loading...[1]
loading...[3]
Here is some text from the server!!

    콜백 함수가 호출될때마다 위의 메세지가 한 줄씩 출력된다.
    프로세스는 다음과 같다.
    - 데이터(data.xt)를 한 뭉치씩 읽어들이는 과정에서 두번 호출(loading...[1] *2)
    - 사용자 인터페이스와 동기를 맞추게 될 시점에 한번 더 호출 (loading...[3])
    - 마지막 "Here is .." 는 완료 상태로서, "data.txt"내용을 읽어들어온 것이다.

6. Ajax가 돋보이는 이유
    Ajax을 사용하는 전략(이유)는 크게 두가지가 있다.
    1) Ajax 기반의 Widget 생성
          몇 가지 파일과 Script 문장만으로 기존 웹 페이지에 추가할 수 있는 위젯을 만들어 낼 수 있다.
          e.g. Google (Ajax) Widget
    2) Desktop 애플리케이션, 윈도우 매니저 같은 Ajax기반 애플리케이션
          전체 웹사이트를 Ajax 애플리케이션럼 만들고, 페이지 단위의 처리를 일부만 사용하는 방법
          e.g. Google Gmail

    하고자 하는 말은, 여태 페이지 단위로 사용자가 이동하는 상황을 묘사하는 스토리를 넘어서,
    일반 애플리케이션과 비슷한 사용자 인터페이스를 웹에 도입하자는 것.
    이를 통해서 사용자가 작업을 수행하는데 좀더 유연하게 대처하게 하자는 것임.