본문으로 바로가기

Ajax 실행 단계별 알아보기

category Web Tech/Ajax 2015. 10. 6. 16:30


Ajax 실행 단계


"Ajax 시작하기"의 앞 선 포스팅에서 Ajax 에 대한 workflow 에 대해 간단히 살펴보았습니다.



다음은 이 실행 순서 단계에 관련된 내용을 설명하도록 하겠습니다.

1. XMLHttpRequest (요청) 객체를 생성

2. 처리 결과를 받을 이벤트 리스너 등록

3. 서버로 보낼 데이터 생성 

4. 클라이언트와 서버 간의 연결 요청 준비(open() 메서드 이용)

4-1. 서버로 보낼 데이터 전송방식 설정(GET, POST 중 선택)

4-2. 서버 응답 방식 설정(동기, 비동기 중 선택)

5. 실제 데이터 전송

6. 응답처리

7. 데이터 처리




XMLHttpRequest 란?


XMLHttpRequest 객체는 Ajax 의 핵심이며, 클라이언트와 서버 간의 통신을 담당하는 객체입니다.

또한 클라이언트와 서버 간에 통신할 때 가장 먼저 생성해야 하는 객체입니다.



다음은 XMLHttpRequest 객체를 생성하는 코드입니다.


window.onload = function() {
// 1. 브라우저에 따른 XMLHttpRequest 생성
var xmlHttp = createXMLHTTPObject();
};

// 1. 브라우저에 따른 XMLHttpRequest 생성
function createXMLHTTPObject() {

var xhr = null;

if(window.XMLHttpRequest) {
// IE7+, 크롬, 사파리, 파폭, 오페라는 XMLHttpRequest 객체를 제공합니다.
xhr = new XMLHttpRequest();
} else {
// IE5,6 버전에서는 다음과 같은 방법으로 XMLHttpRequest 객체를 생성해야 합니다.
xhr = new ActiveXObject('Microsoft.XMLHTTP');
}

return xhr;

}


대부분의 브라우저에서 XMLHttpRequest 객체를 제공하고 있으며, IE 5,6 버전을 사용하지 않는 추세이고 해당 프로젝트에서 IE6이하는 고려하지 않는다면 위와 같은 코드를 작성하지 않아도 됩니다.


위의 부분은 거의 공식처럼 사용되는 코드이며 jQuery Ajax 내부에도 이와 같은 방식으로 XMLHttpRequest  객체를 생성합니다. 

이 후 포스팅에서 다루겠지만 jQuery Ajax 에는 바로 위와 같은 작업이 모두 포장되어 있어서 더욱 쉽게 사용할 수 있습니다.

하지만 jQuery Ajax 역시 자바스크립트 Ajax 의 라이브러리에 불과하므로 Ajax 를 이해하는  것이 보다 중요합니다.

이어서 XMLHttpRequest 객체의 주요 메서드와 프로퍼티에 대해 알아보겠습니다.



주요 메서드


 메서드 명

설     명 

매개 변수 

반환값 

 open(

method, 

url, 

[async:true]

 ) 

요청 매개변수를 초기화하는 메서드로써 URL 에 지정한 서버의 페이지에 어떤 내용을 요청하는데 데이터는 GET/POST 방식으로 보낼 것이고 응답은 동기/비동기로 받을 것이기에 여기에 맞게 XMLHttpRequest 객체를 준비하라는 것과 같습니다.

- method : 데이터 전송방식(GET/POST)

- url : 요청대상 URL 입니다.

- async : 요청에 대한 응답을 기다리는 방식을 나타냅니다. 

비동기(true: 기본값)와 동기(false) 방식이 있습니다. 

없음 

  send(data

HTTP 요청을 실제로 실행하는 메서드입니다. 

이 메서드가 실행돼야 비로소 요청이 서버에 전달되기 시작합니다.

- data : POST 방식으로 보낼 데이터 

음 



주요 프로퍼티


 프로퍼티

설     명 

 readyState

요청상태를 나타내며, 이 프로퍼티를 이용하면 클라이언트와 서버 간의 데이터 통신이 현재 어디까지 진행되고 있는지 확인 할 수 있습니다.


아래는 주요 상태 정보입니다.

0 = 초기화 되지 않은 상태

1 = 로드되지 않은 상태 (즉, send() 메서드가 호출되지 않은 상태)

2 = 로드된 상태. 헤더와 상태는 받았으나 아직 응답을 받지 못한 상태.

3 = 상호작용 상태. 데이터의 일부분만 받은 상태.

4 = 완료 상태. 모든 데이터를 받아서 완료된 상태.

 onreadystatechange

청상태가 변경될 때 발생하는 이벤트입니다. 

 responseText 

서버 응답에 반환된 본문 콘텐츠입니다. 

 responseXML 

서버 응답이 XML 인 경우 이 프로퍼티에 XML 본문 콘텐츠로 채워집니다. 

 status 

서버 응답 상태를 나타냅니다.

200 = 성공

404 = 페이지를 찾을 수 없음

 statusText 

응답으로 반환된 상태 메시지입니다. 






응답 이벤트 처리 (요청에 대한 응답처리 이벤트 리스너 등록)

XMLHttpRequest 객체의 onreadystatechange 이벤트는 클라이언트와 서버 간의 데이터 전송 상태가 바뀔 때마다 발생하는 이벤트입니다.

즉, 서버가 클라이언트가 요청한 응답으로 보내는 데이터를 얻으려면 이 이벤트를 사용해야 한다는 의미입니다.

이를 위해서는 먼저 실제 데이터 전송이 이뤄지기 전에 다음과 같이 이벤트 리스너를 등록해야 합니다.


// 요청에 대한 응답 처리 이벤트 리스너 등록
xmlHttp.onreadystatechange = on_ReadyStateChange;


이후에 연결 요청 준비 단계(open() 메서드)와 와 실제 데이터 전송(send() 메서드)이 이루어지면 앞의 코드, 이벤트 리스너로 등록한 on_ReadyStateChange() 리스너 함수가 실행되고 데이터를 주고 받는 과정에서 통신이 정상적으로 이루어 졌다면 그 시점이 언제인지를 알아내기만 하면 됩니다.


통신 시점의 상태를 알아내는 코드는 다음과 같습니다.


// 응답 처리
function on_ReadyStateChange() {
/**
* 0 = 초기화 전
* 1 = 로딩 중
* 2 = 로딩 됨
* 3 = 대화 상태
* 4 = 데이터 전송완료
*/
// 4 = 데이터 전송완료
if(xmlHttp.readyState == 4) {
// 200 은 에러 없음을 의미 ( 404 = 페이지가 존재하지 않음 )
if(xmlHttp.status == 200) {
/**
* ----------------------------------
* 이 영역에서 서버에서 보낸 데이터를
* 타입(XML, JSON, CSV) 에 따라 처리
* ----------------------------------
*/
} else {
alert('처리 중 에러가 발생했습니다.')
}
}

}


정상적으로 서버와의 통신이 이루어졌다면 이때 서버에서 보내온 데이터가 담긴 responseText 와 responseXML 프로퍼티를 사용하면 됩니다.


여기까지가 응답 이벤트 처리와 관련된 내용입니다.




GET 방식, POST 방식

GET 과 POST 는 HTTP 메서드의 한 종류이며, HTTP 메서드는 클라이언트 데이터(매개변수)를 서버로 보내는 방식을 의미합니다.

HTTP 메서드로는 GET, POST 이외에 PUT, TRACE 와 같은 메서드가 있으며, 대표적으로 GET 과 POST 방식을 가장 많이 사용합니다.



GET 방식

서버로 보낼 클라이언트의 데이터를 URL 에 포함시켜서 보내는 방법을 GET 방식이라고 합니다.


형식

- http://주소?매개변수=값&매개변수=값....

- http://erum.com/index.jsp?name=dream&pw=1234


위와 같이 GET 방식으로 서버에 데이터를 보내는 경우는 주소 다음에 "?" 를 넣은 후 매개변수=값을 넣어줍니다. 데이터가 여러개인 경우는 구분자로 "&"를 사용합니다. 


GET 방식으로는 보낼 수 있는 데이터의 양이 정해져 있기 때문에 간단한 데이터를 보낼 때 주로 사용합니다. 또한 URL에 데이터를 포함시켜 보내다 보니 전송하는 내용이 모두 눈이 보이기 때문에 중요한 데이터 내용이 포함된 경우는 GET 방식으로는 보내지 않는 편이 바람직합니다.


적용방법

XMLHttpRequest 의 open() 메서드의 첫 번째 매개변수로 "GET" 을 넣어주고, 두번째 인자는 서버로 보낼 데이터가 있는 경우 요청 URL에 데이터를 문자열로 넣어줍니다.




var data = 'id=eroom&pw=1234';
xmlHttp.open('GET', 'index.jsp?' + data, true);

// 서버로 보낼 데이터가 없는 경우라면 요청 URL 만 작성

xmlHttp.open('GET', 'index.jsp', true);


마지막으로 xmlHttp.send(null) 메서드를 실행하면 통신이 시작됩니다.


참고로 세번째 매개변수의 true 는 비동기를 뜻합니다.




POST 방식

GET 방식과는 달리 POST 방식은 많은 양의 데이터를 한꺼번에 보낼 때 특히 유용합니다.


일반적으로 POST 방식은 폼(Form) 태그 안에 입력한 사용자 정보를 보낼 때 주로 사용합니다.


만약에 GET 방식으로 보낸다면 전송해야 할 내용을 모두 문자열로 만들어야 하기 때문에 다음과 같이 번거로운 작업을 해야 합니다.


url+?매개변수=&매개변수= ...


POST 방식은 위와 같은 작업을 하지 않고도 폼 태그 내부에 정보를 매우 쉽게 데이터를 한번에 전송할 수 있습니다.


하지만 Ajax 에서는 POST 방식으로 데이터를 보낼 때 폼 태그에 실어서 보내는게 아니라 GET 방식처럼 약간의 번거로운 작업이 필요합니다.



적용방법


XMLHttpRequest 의 open() 메서드의 첫 번째 매개변수로 "POST" 을 넣어주고, 두번째 인자는 서버로 보낼 데이터를 뺀 요청할 URL만 지정합니다. 그리고 세번째 매개변수는 대부분 비동기로 응답을 받기 때문에 true 를 지정합니다.


xmlHttp.open('POST','index.jsp',true);
xmlHttp.setRequestHeader('Content-Type','application/x-www-form-urlencoded');


그리고 POST 방식에서는 위와 같이 setRequestHeader 에 콘텐츠 타입이 form-urlencode 임을 지정해야 합니다.


GET 방식에서는 send() 메서드에 null 을 지정했던 것과 달리 POST 방식에서는 send() 메서드의 매개변수 값으로 서버로 보낼 데이터를 넣어서 실행하면 통신이 시작됩니다.


xmlHttp.send('id=jaehee&pw=1234');





서버 응답 방식 설정 - Ajax 동기/비공기 응답 설정

동기/비동기는 서버에 원하는 요청을 보낻고 이에 대한 응답이 올 때까지 어떤 식으로 기다릴지를 나타냅니다.




동기(Synchronous) 방식

동기 방식의 예제 코드를 살펴보겠습니다.


window.onload = function() {

// 1. 요청 객체 생성 : 웹 표준 지원 브라우저일 경우
var xmlHttp = new XMLHttpRequest();

// 2. 요청에 대한 응답 처리 이벤트 리스너 등록
xmlHttp.onreadystatechange = on_ReadyStateChange;

// 3. 서버로 보낼 매개변수 생성
var strParam = 'id=jaehee&pw=1234';

// 4. 클라이언트와 서버 간의 연결 요청 준비(open() 메서드 이용)
xmlHttp.open('GET','test.jsp?' + strParam, false);

// 5. 실제 데이터 전송(send() 메서드 이용)
xmlHttp.send('id=jaehee&pw=1234');

// Transmit ::: 동기/ 비동기 실행 테스트
alert('전송 시작');

};

// 6. 응답처리
function on_ReadyStateChange() {
/**
* 0 = 초기화 전
* 1 = 로딩 중
* 2 = 로딩 됨
* 3 = 대화 상태
* 4 = 데이터 전송완료
*/
// 4 = 데이터 전송완료
if(xmlHttp.readyState == 4) {
// 200 은 에러 없음= ( 404 = 페이지가 존재하지 않음 )
if(xmlHttp.status == 200) {

// 7. 데이터 처리
/**
* ----------------------------------------------------------------------------
* 이 영역에서 서버에서 보낸 데이터를 타입(XML, JSON, CSV) 에 따라 처리
* ----------------------------------------------------------------------------
*/
console.log('이 부분에서 데이터를 처리합니다.');
} else {
console.log('처리 중 에러가 발생했습니다.');
}
}

}


동기 방식에서는 send() 메서드에 의해 서버 통신이 시작되면 send() 이후의 


5. 실제 데이터전송

6. 응답 처리

7. CSV, XML, JSON 에 따른 데이터 처리


Transmit 부분

5,6,7 의 단계를 실행하고, 클라이언트와 서버 간의 요청과 응답이 모두 끝나면 Transmit 부분의 내용이 실행됩니다.


다시 말해서 5 단계의 send() 메서드에 의해 실제 데이터 통신,전송이 이루어지면 잠시 후에 클라이언트에 대한 요청 응답이 정상적으로 이루어진 경우 on_ReadyStateChange() 함수 내부의 7 단계의 구문이 실행됩니다. 이와 관련된 모든 처리가 끝나면 비로소 Transmit 단계 부분의 구문이 실행됩니다.


이렇게 실행되기 때문에 동기 방식이라고 합니다. 


다만, 동기 방식은 특성상 요청에 대한 응답이 언제 올지 모르기 때문에 다른 일들을 아무것도 처리하지 못한 채 기다려야 하기 때문에 특별한 경우를 제외하고는 거의 사용하지 않습니다. 




비동기(Asynchronous) 방식

비동기 방식은 동기 방식의 반대로 서버 요청에 대한 응답을 무작정 기다리는 것이 아니라 응답을 보낸 후 바로 다음 작업을 진행할 수 있습니다.

비동기 방식에서는 open() 메서드의 세 번째 매개변수로 false 대신 true 를 지정하기만 하면 비동기로 응답 받을 수 있습니다.


window.onload = function() {

// 1. 요청 객체 생성 : 웹 표준 지원 브라우저일 경우
var xmlHttp = new XMLHttpRequest();

// 2. 요청에 대한 응답 처리 이벤트 리스너 등록
xmlHttp.onreadystatechange = on_ReadyStateChange;

// 3. 서버로 보낼 매개변수 생성
var strParam = 'id=jaehee&pw=1234';

// 4. 클라이언트와 서버 간의 연결 요청 준비(open() 메서드 이용)
xmlHttp.open('GET','test.jsp?' + strParam, true);

// 5. 실제 데이터 전송(send() 메서드 이용)
xmlHttp.send('id=jaehee&pw=1234');

// Transmit ::: 동기/ 비동기 실행 테스트
alert('전송 시작');

};

// 6. 응답처리
function on_ReadyStateChange() {
// 4 = 데이터 전송완료
if(xmlHttp.readyState == 4) {
// 200 은 에러 없음= ( 404 = 페이지가 존재하지 않음 )
if(xmlHttp.status == 200) {
// 7. 데이터 처리
// 이 영역에서 서버에서 보낸 데이터를 타입(XML, JSON, CSV) 에 따라 처리
console.log('이 부분에서 데이터를 처리합니다.');
} else {
console.log('처리 중 에러가 발생했습니다.');
}
}

}


비동기 방식에서는 5 단계의 send() 메서드에 의해 데이터가 전송되면 Transmit 단계에 해당하는 구분이 아무런 기다림 없이 바로 실행되게 됩니다. 그리고 이 후 클라이언트에 대한 요청이 모두 정상적으로 이루어 지면 7번에 해당하는 구문이 실행됩니다.


아래와 같은 단계 순으로 진행됩니다.


5. 실제 데이터전송

Transmit 부분

6. 응답 처리

7. CSV, XML, JSON 에 따른 데이터 처리


즉, 동기 방식과 비동기 방식의 가장 큰 차이점은 send() 메서드를 실행하여 클라이언트 요청을 서버로 보낸 후에 응답이 올 때까지 다음 구문인 Transmit 영역을 실행하지 않고 그 자리에서 다른 일을 아무것도 하지 않은 채 기다릴지(동기방식), 아니면 기다리지 않고 바로 이어서 그 다음 구문을 실행할 것(비동기식)인지에 있습니다.


이 부분을 제외하면 동기와 비동기의 차이점은 없습니다.





응답형식

send() 함수가 실행되면 요청이 서버로 전송되고 그 이후 서버는 요청에 대한 응답으로 데이터를 보내주는데, 이때 서버에서는 주로 CSV, XML, JSON 이라는 세 가지 데이터 타입 중의 하나를 선택한 후 이 타입에 맞게 데이터를 가공해서 보내주게 됩니다.


그리고 클라이언트에서는 이렇게 받은 응답 데이터를 데이터 형식에 맞게 변환하여 사용하게 됩니다.


이러한 세가지 데이터 형식에 대해 알아보도록 하겠습니다.





CSV(Comma Separated Value)

CSV 는 세가지 타입 중에 가장 단순하면서 평범한 텍스트 형식입니다. CSV 풀네임에서도 알 수 있듯이 서버 측 응답 내용에 특정 구분자를 추가해서 하나의 문자열로 보내는 방식을 말합니다. 구분자로는 콤마(Comma) 말고도 사용자가 원하는 문자를 사용할 수 있습니다.


서버에서는 다음과 같이 클라이언트 요청에 대한 결과값을 특정 구분자로 묶어 하나의 기다란 문자열로 만들어 응답으로 보냅니다.


/**
사용된 구분자 = ","
"jaehee,1234"

사용된 구분자 = "||"
"id=jaehee||pw=1234"

사용된 구분자 = "&"
"id=jaehee&pw=1234"
*/


// 클라이언트는 서버에서 사용한 구분자를 토대로 결과값을 분리해서 데이터를 처리
var aryData = xmlHttp.responseText.split('||');
var objResult = {};
for(var i =0; i < aryData.length; i++) {
var keyValue = aryData[i].split('=');
objResult[keyValue[0]] = keyValue[1];
}


위와 같이 사용되는 타입을 CSV 라고 합니다.





XML

서버에서는 다음과 같은 형태로 응답을 XML 형식으로 클라이언트에 보내줍니다.


header('Content-Type:text/xml; charset=utf-8');
<result>
<success>1</success>
<id>jaehee</id>
<pw>1234</pw>
</result>


그러면 클라이언트에서는 다음과 같은 식으로 XML 을 파싱해서 데이터를 처리합니다.


var xmlHttp = new XMLHttpRequest();

// JavaScript DOM
var xmlInfo = xmlHttp.responseXML;
var id = xmlInfo.getElementsByTagName('id')[0];
var pw = xmlInfo.getElementsByTagName('pw')[0];
console.log('id=' + id.firstChild.nodeValue);
console.log('pw=' + pw.firstChild.nodeValue);

// jQuery DOM
$xmlInfo = $(xmlHTTp.responseXML);
var id = $xmlInfo.find('id').text();
var pw = $xmlInfo.find('pw').text();
console.log('id=' + id);
console.log('pw=' + pw);




JSON(JavaScript Object Notation)

JSON 도 CSV 와 마찬가지로 특정 규칙에 정해진 형식으로써 자바스크립트 객체 구조를 지닌 문자열입니다.


다음은 객체 리터럴 방식으로 정의한 자바스크립트의 객체입니다.


{
id : "jaehee",
pw : "1234"

}


위의 객체를 그대로 다음과 같이 문자열로 만들어 보겠습니다.


var str = '{';
str += ' "id" : "jaehee",';
str += ' "pw" : "1234",';
str += '}';


바로 이런 스타일을 JSON 형식이라고 합니다.



실제 예를 간단히 살펴 보겠습니다.

서버에서는 아래와 같이 응답을 JSON 형식 문자열로 클라이언트에게 보냅니다.


$result = '{';
$result. = ' "id" : "jaehee",';
$result. = ' "pw" : "1234",';
$result. = '}';

echo($result);


그러면 클라이언트에서는 응답받은 JSON 형식 문자열을 자바스크립트 객체로 만들어 처리합니다.


var xmlHttp = new XMLHttpRequest();

var objResult = eval('(' + xmlHttp.responseText + ')');
alert('id = ' + objResult.id);
alert('pw = ' + objResult.pw);


지금까지 Ajax 와 관련된 기초적인 내용과 용어를 알아 보았습니다.


다음에는 Ajax 를 활용한 핵심 내용단계를 살펴보도록 하겠습니다.




Jaehee's WebClub