JavaScript, jQuery, 그리고 Ajax
Ajax는 Asynchronous JavaScript And XML의 약어로 언어나 프레임 워크가 아닌 구현하는 방식을 의미합니다. 데이터를 이동하고 화면을 구성하는데 있어서 웹 화면을 갱신하지 않고 필요한 데이터를 서버로 보내고 가져오는 방법입니다. 화면 갱신이 없어서 사용자 입장에서는 매우 편리하고 빠르게 작업을 처리하는 것처럼 느끼게 합니다. 하지만, 동적으로 화면을 구성하는 만큼 개발자의 구현은 복잡해 집니다.
데이터 전송
Ajax는 앞서 말했 듯 서버와 클라이언트(사용자)간에 데이터를 이동하고 화면을 구성하는 구현 방식입니다. Ajax의 구현에 들어가기 앞서 Ajax에서의 데이터 전송은 어떤식으로 진행 되는 가에 대해서 살짝 살펴보고 가겠습니다.
위 그림1은 동기식 데이터 전송에 대한 그림 입니다. 동기화란 사전적 의미로 "작업들 사이의 수행 시기를 맞추는 것. 사건이 동시에 일어나거나, 일정한 간격을 두고 일어나도록 시간의 간격을 조정하는 것"을 말합니다. 즉, 웹 화면 구성에서의 동기화란 위 그림1 처럼 서버로 데이터를 요청하고 응답이 오는 시간동안 작업을 멈추고 기다리는 것을 뜻합니다. 예를 들면 수 많은 웹에서 로그인을 할 때 아이디와 패스워드를 입력하여 서버로 전송하고 서버로 부터 응답을 받은 후 로그인 성공, 실패 웹 페이지로 이동 하는 것이 대표적인 동기식 데이터 전송입니다.
위 그림 2는 Ajax 통신에 대한 그림입니다. Ajax는 비동기 식으로 데이터 전송을 진행합니다. 위 그림2 처럼 서버로 데이터를 요청하고 응답을 기다리는 동안 웹은 자신의 다른 업무를 진행하고 응답이 오면 그 후 작업을 진행 합니다. 즉, 사용자 입장에서는 화면 갱신도 없고, 요청-응답 사이 시간에도 다른 일을 진행 할 수 있기 때문에 편리하고 빠르게 작업을 처리하는 것처럼 느낍니다.
데이터 형식
데이터를 전송하는데 있어 전송 형식은 여러 종류가 있지만, Ajax 통신에서 데이터를 전송하는 형식은 크게 세가지로 나눌 수 있습니다. 바로 CSV, JSON, XML형식입니다. 아래는 데이터 형식의 예와 설명입니다.
CSV 형식
term, part, definition
BACCHUS. 바쿠스,명사.,고대인들이 술에 취할 명분으로 편의상 만들어낸 신.
BACKBITE. 험담하다,동사.,상대방에게 들킬 염려가 없을 때, 그에 관해 본 그대로를 입에담다.
BANG. 빵! 가지런한 앞머리,명사.,총 쏘는 소리. 앞머리를 잘라 내린 여성의 머리모양
위는 CSV형식의 예입니다. CSV형식은 ,로 데이터의 속성을 나누고 줄바꿈으로 데이터를 나눕니다. 용량이 적다는 장점이 있지만 가독성이 떨어진다는 단점이 있습니다.
XML 형식
<entries>
<entry term="BACCHUS. 바쿠스" part="명사.">
<definition>
고대인들이 술에 취할 명분으로 편의상 만들어낸 신.
</definition>
</entry>
<entry term="BACKBITE. 험담하다" part="동사.">
<definition>
상대방에게 들킬 염려가 없을 때, 그에 관해 본 그대로를 입에담다.
</definition>
</entry>
<entry term="BANG. 빵! 가지런한 앞머리" part="명사.">
<definition>
총 쏘는 소리. 앞머리를 잘라 내린 여성의 머리모양
</definition>
</entry>
</entries>
위는 XML형식의 예입니다. XML형식은 CSV형식의 가독성을 개선하기 위해 나온 데이터 형식입니다. 태그로 속성과 데이터를 구분 합니다. 가독성은 좋지만 용량이 크며 데이터가 많아 지면 분석속도가 떨어진다는 단점이 있습니다.
JSON형식
[{
"term": "BACCHUS. 바쿠스",
"part": "명사.",
"definition": "고대인들이 술에 취할 명분으로 편의상 만들어낸 신."
},
{
"term": "BACKBITE. 험담하다",
"part": "동사.",
"definition": "상대방에게 들킬 염려가 없을 때, 그에 관해 본 그대로를 입에담다."
},
{
"term": "BANG. 빵! 가지런한 앞머리",
"part": "명사.",
"definition": "총 쏘는 소리. 앞머리를 잘라 내린 여성의 머리모양."
}]
위는 JSON형식의 예입니다. JSON형식은 JavaScript의 객체 형태로 데이터를 전송하는 형식입니다. XML형식과 CSV형식의 단점을 최소화한 형식으로 현재 가장 많이 쓰이는 형식입니다. 가독성도 좋고 용량이 적다는 장점을 가지지만 여전히 데이터 양이 많으면 분석속도가 떨어진다는 단점이 있습니다.
데이터 전송 방식
데이터 전송 방식은 여러 종류가 존재합니다. 본문에서는 다음과 같은 데이터 전송 방식을 언급하려고 합니다.
- GET : 지정한 URI의 데이터를 열람하기 위한 메소드
- POST : 지정한 URI에 데이터를 생성하기 위한 메소드
- PUT : 지정한 URI의 데이터를 갱신하기 위한 메소드
- DELETE : 지정한 URI의 데이터를 삭제하기 위한 메소드
- HEAD : 지정한 URI의 헤더 정보를 요청하는 메소드
위에서 언급한 데이터 전송 방식은 흔히 말하는 CRUD(생성,열람,수정,삭제)방식들이라고 생각하시면 쉽습니다. 하지만 , 보안 및 특정 브라우저에서 지원하지 않는 문제(PUT, DELETE)로 인해 GET,POST방식이 많이 쓰이고 있습니다. 본문에서는 GET방식과 POST방식에 많은 비중을 두고 설명하려고 합니다. 다른 방식에 대해서 궁금하신 분들은 아래 참조링크에서 확인 해주세요.
많은 개발자들이 GET방식과 POST방식을 헷갈려 하고 혼용해서 사용하고 있습니다. GET,POST방식의 용도에 대해 간단하게 설명 드리자면 데이터의 변경 유무라고 할 수 있습니다. GET방식의 경우 데이터를 단순히 읽어 오는 경우에 쓰이며 POST방식의 경우 데이터를 생성,수정,삭제 하는 경우(위에서 언급한 PUT,DELETE의 역할까지). 즉 , 데이터를 변경하는 경우에 사용되는 방식입니다. GET방식의 경우 데이터 전송량이 POST방식 보다 적고 URL에 정보가 고스란히 담겨있어 최소한의 보안도 되지 않기 때문이기도 합니다. 하지만, 그 만큼 사용이 간편하여 대부분의 http호출에도 GET방식이 사용됩니다.
단순히 데이터를 읽어 들이는 경우에 GET방식이 아닌 POST방식이 쓰일 때 가 있습니다. 그 예로 로그인의 경우 사용자의 아이디와 패스워드만 서버에 전송하여 데이터를 읽어 들이면 되지만 사용자의 개인정보가 URL에 노출이 되므로 POST방식을 사용합니다.
JavaScript Ajax
그럼, 간단하게 JavaScript에서의 Ajax구현 방법을 보겠습니다.
JavaScript Ajax구현에 있어서 XMLHttpRequest객체(이하 XHR)는 반드시 필요한 객체입니다. 대부분의 웹브라우저는 XHR을 지원해 주지만 인터넷 익스플로러(IE), 특히 IE7이하 버전에서는 지원해주지 않습니다. 그렇기 때문에 XHR을 쓰지 않고 IE에서 지원해주는 ActiveXObject를 사용합니다. XHR이 ActiveXObject를 모방하여 만들어 졌으므로 구현에는 별로 차이가 없습니다.
//객체 생성부분
var xmlhttp;
if (window.XMLHttpRequest) {
xmlhttp = new XMLHttpRequest();
}
else {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
//Ajax구현부분
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
//통신 성공시 구현부분
}
}
xmlhttp.open("GET", "exam.xml", true);
xmlhttp.send();
위 예제코드는 JavaScript Ajax 간단한 구현 예제입니다. 위 코드와 같이 XHR를 생성한 후 생성된 객체를 통해 Ajax를 구현합니다. XHR의 함수는 크게 다음과 같이 나뉩니다.
- onreadystatechange : 비동기 통신시 서버와의 통신이 이루어 진 후 동작될 함수를 말합니다.
- send : 데이터 교환을 요청하는 함수입니다.
- open(GET or POST, url, async) : 서버와 데이터를 교환할 때 필요한 정보를 입력합니다. 첫번째 인자값은 Get,Post를 지정해주며 두번째 인자 값은 데이터를 교환할 서버의 url을, 세번째 인자 값은 비동기로 진행할 것인지에 대해서 입력해줍니다. 동기로 진행할 경우 위 onreadystatechange 함수 필요없이 응답을 기다렸다가 send함수 뒤에 나오는 script코드를 응답이 오면 동작하게 됩니다.
JavaScript에서 ajax를 구현하기 위해서는XHR의 함수도 잘 알아야 하지만 속성도 잘알아둬야 합니다. onreadystatechange함수 내에서 조건에 따라 처리해주는 구현이 다를 수 있기 때문입니다. 속성중 가장 중요한 속성을 나열 하면 다음과 같습니다.
readyState : ajax통신의 진행중인 상태를 알려줍니다. 값에 따라 의미하는 상태는 다음과 같습니다.
0 : 초기화 되지 않은 상태 (open메소드가 아직 호출되지 않은 상태)
1 : open메소드가 호출된 상태 (send메소드는 호출 되지 않은 상태)
2 : 송신완료, 요청을 시작한 상태 ( 요청은 하지 않았지만 데이터가 아직 오지 않은 상태)
3 : 수신 중인 상태 (데이터가 들어오고 있는 상태)
4 : 수신 완료 (데이터를 모두 받은 상태)
Status : 데이터 수신의 성공 여부를 판단해주는 속성입니다 값에 따라 의미하는 상태는 다음과 같습니다
0 : 로컬로 접근 성공을 의미합니다.
200 : 해당 url로 접근 성공을 의미합니다.
403 : 접근이 거부되었음을 의미합니다.
404 : 해당 url이 없음을 의미합니다.
500 : 서버오류를 의미합니다.
responseXML : 받은 데이터를 XML타입으로 변환 시켜줍니다.
responseText : 받은 데이터를 텍스트 타입으로 변환 시켜줍니다.
JavaScript의 Ajax는 텍스트 또는 XML타입으로만 데이터를 가져올 수 있습니다. 그렇기 때문에 JSON형식이나 CSV형식으로 데이터를 가져오기 위해서는 서버에서 텍스트(문자열) 형식으로 CSV 또는 JSON모양을 잡아주고 (예: "{'term' : "+term+", 'part' : "+part+" }") 데이터를 보냅니다. 자바스크립트 Ajax구현부에서 JSON 표현식으로 데이터를 받아왔을 때 받아온 데이터를 JSON형식으로 파싱해줍니다. 자세한 CSV, XML, JSON 데이터를 다루는법은 뒤에서 설명하겠습니다. 아래는 파싱의 예입니다.
//JSON파싱
JSON.parse(xmlhttp.responseText);
//IE(JSON 지원 안해주는 버전)에서의 파싱
eval("("+xmlhttp.responseText+")");
jQuery Ajax
jQuery 라이브러리에서의 Ajax는 보다 다양하고 단순한 방법으로 JavaScript Ajax의 구현을 할 수 있게 해줍니다. 순수 JavaScript로 Ajax를 구현 하는 것보다 좀 더 명시적으로 코드를 작성할 수 있다는 장점도 있습니다. 아래에서 jQuery 라이브러리의 Ajax구현 함수들을 살펴 보겠습니다. 아래 main page는 jQuery Ajax에서 계속 사용될 예제 코드입니다.
// main page
<html>
<head></head>
<body>
<div id="container">
<div class="letters">
<div class="letter" id="load">
<h3><a href="#">LOAD함수</a></h3>
</div>
<div class="letter" id="ajax">
<h3><a href="#">AJAX함수</a></h3>
</div>
<div class="letter" id="get">
<h3><a href="#">GET함수</a></h3>
</div>
<div class="letter" id="json">
<h3><a href="#">GETJSON함수</a></h3>
</div>
<div class="letter" id="script">
<h3><a href="#">GETSCRIPT함수</a></h3>
</div>
</div>
<div id="dictionary">
</div>
</div>
<script src="http://code.jquery.com/jquery-1.10.2.js"
type="text/javascript"></script>
<script src="dictionary.js" type="text/javascript"></script>
</body>
</html>
load함수
load함수는 다음과 같은 표현식으로 구현이 됩니다.
$(Selector).load( URL , DATA , CALLBACK);
해당 Selector(DOM)객체에 첫번째 매개변수인 URL에 해당하는 html등의 웹페이지 또는 파일을 전체화면의 재구성 없이 동적으로 구성하는 함수입니다. 두번째 매개변수를 통하여 데이터를 전송 할 수 있으며 세번째 매개변수를 통해 통신이 완료된 이후의 작업을 수행 할 수 있습니다. 또한 URL에 해당 URL의 특정 DOM객체에 접근하여 그 DOM객체 만을 불러올 수도 있습니다.(예: $(selector).load('exam.html img) - selector에 exam.html 의 img태그를 가져다 붙임)
// load.html
<div class="entry">
<h3 class="term">BACCHUS. 바쿠스</h3>
<div class="part">명사.</div>
<div class="definition">
고대인들이 술에 취할 명분으로 편의상 만들어 낸 신
</div>
</div>
<div class="entry">
<h3 class="term">BACKBITE. 험담하다</h3>
<div class="part">동사.</div>
<div class="definition">
상대방에게 들킬 염려가 없을 때, 그에 관해 본 그대로를 입에담다.
</div>
</div>
<div class="entry">
<h3 class="term">BANG. 빵! 가지런한 앞머리</h3>
<div class="part">명사.</div>
<div class="definition">
총쏘는 소리. 앞머리를 잘라 내린 여성의 머리모양
</div>
</div>
//dictionary.js 구현
$(document).ready(function() {
$('#load').click(function() {
$('#dictionary').load("load.html");
return false;
});
});
위 예제 코드는 load함수를 구현하기 위한 예제 코드입니다. 가져올 URL(load.html)이 위의 코드이며 아래 코드가 JavaScript에서의 load함수 구현 코드 입니다. id를 load로가진 a태그를 클릭하게되면 load.html을 불러다 id를 dictionary로 가진 div태그에 붙여 줍니다. 아래 그림은 위 코드의 결과 입니다.
ajax함수
ajax함수는 다음과 같은 표현식으로 구현이 되며, options에 들어갈 속성을 아래에 정리해 놓았습니다. 더 자세한 사항은 넥스트리 블로그에 게시된 김재훈 님의 Ajax를 품은 jQuery를 참조하시면 됩니다.
$.ajax(options);
- url : 통신을 원하고자 하는 URL주소를 입력합니다.(필수 입력 값)
- data : 서버로 보낼 데이터를 입력합니다.
- type : GET, POST등의 통신 방식 지정합니다.
- dataType : 통신의 결과로 넘어올 데이터의 종류를 지정합니다.
- success(data) : 통신 성공시 호출 해야하는 함수를 지정합니다. 매개변수로 결과로 넘어온 데이터를 받습니다.
- error : 통신 실패시 호출 해야하는 함수를 지정합니다.
- complete : 통신 성공 여부와 관계없이 통신이 끝난 후 호출 해야하는 함수를 지정합니다.
- beforeSend : 통신 전에 호출 해야하는 함수를 지정합니다.
- async : 비동기(true), 동기(false) 여부를 지정합니다.
//dictionary.js 구현
$(document).ready(function() {
$('#ajax').click(function() {
$.ajax({
url:'ajax.xml',
type:'GET',
dataType: 'xml',
success: function(data){
$('#dictionary').empty();
$.each($(data).find('entry'), function(){
var $entry = $(this);
var html ='<div class="entry">';
html +='<h3 class="term">'+ $entry.attr('term'); +'</h3>';
html +='<div class="part">'+ $entry.attr('part'); +'</div>';
html +='<div class="definition">'+ $entry.text()+'</div>';
html +='</div>';
$('#dictionary').append(html);
});// end each
}// end
});// end ajax
return false;
});
});
위 예제 코드는 ajax함수 구현에 관한 간단한 예제입니다. ajax.xml에 접근하여 GET방식으로 XML형식으로 데이터를 불러들이고 요청이 성공하면 success 옵션을 사용하여 WEB화면을 구성하는 코드입니다. 즉, data는 XML 형식이기 때문에 jQuery 객체로 파싱해준 후에 find함수를 이용하여 entry태그에 접근을 합니다. 그 후 entry가 가진 속성들을 뽑아내어 WEB화면을 구성 하고 있습니다. ajax.xml은 위에 소개한 데이터 형식(XML형식)으로 구성되었습니다. 아래 그림은 위 코드의 결과 입니다.
get,post함수
get함수와 post함수는 ajax함수의 약식으로 get함수는 GET방식으로, post함수는 POST방식으로 작동을 합니다. 다음과 같은 표현식으로 구현 됩니다.
//get함수
$.get ( URL , DATA , CALLBACK);
//post함수
$.post ( URL , DATA , CALLBACK);
첫번 째 매개 변수로는 요청을 보낼 URL주소를 입력하게되며, 두번째 매개 변수로는 요청에 보낼 데이터를 세번 째 매개변수로는 통신 성공시 구현하게될 콜백 함수를 정의해 주게 됩니다.
//dictionary.js 구현
$(document).ready(function() {
$('#get').click(function() {
$.get('ajax.xml', function(data) { // data에 날라옴 자바스크립트로
$('#dictionary').empty();
$(data).find('entry').each(function() {
var $entry = $(this);
var html = '<div class="entry">';
html += '<h3 class="term">' + $entry.attr('term');+'</h3>';
html += '<div class="part">' + $entry.attr('part'); +'</div>';
html += '<div class="definition">' + $entry.text() + '</div>';
html += '</div>';
$('#dictionary').append(html);
});
});
return false;
});
});
위 예제 코드는 get함수 구현에 관한 간단한 예제 코드입니다. 위 ajax함수 구현 예제 코드와 CALLBACK 함수 구현은 같으며 앞 서 말했 듯 ajax의 약식으로 구현이 가능합니다. ajax함수는 많은 option값을 넣지만 get,post 함수는 URL, DATA, CALLBACK 만 정의해주면 구현이 가능합니다. 아래 그림은 위 코드의 결과 입니다.
getJSON함수
위 함수들과 마찬가지로 getJSON함수는 ajax함수의 약식입니다. JSON형식의 데이터를 불러 읽을 때 쓰이는 함수이며 GET방식으로 통신이 이루어 집니다. getJSON함수는 다음과 같은 표현식으로 구현 됩니다.
$.getJSON( URL , DATA , CALLBACK);
첫번 째 매개 변수로는 요청을 보낼 URL주소를 입력하게되며, 두번째 매개 변수로는 요청에 보낼 데이터를 세번 째 매개변수로는 통신 성공시 구현하게될 콜백 함수를 정의해 주게 됩니다.
//dictionary.js 구현
$(document).ready(function() {
$('#json').click(function() {
$.getJSON('json.json',function(data){
$('#dictionary').empty();
$.each(data,function(index,entry){
var html ='<div class="entry">';
html +='<h3 class="term">'+entry.term +'</h3>';
html +='<div class="part">'+entry.part +'</div>';
html +='<div class="definition">'+ entry.definition+'</div>';
html +='</div>';
$('#dictionary').append(html);
});// end each
});// end json
return false;
});// end click
});
위 예제 코드는 getJSON함수의 간단한 구현 예제 코드입니다. 앞 서 말했듯 ajax 함수의 약식으로 구현이 되며, 응답 data가 JSON형식. 즉, JavaScript 객체 형식으로 나오기 때문에 JavaScript 객체 처럼 활용이 가능합니다. 아래 그림은 위 코드의 결과 입니다.
getSscript함수
getScript함수도 마찬가지로 ajax함수의 약식입니다. Script파일을 불러 읽을 때 쓰이는 함수이며 GET방식으로 통신이 이루어 집니다. getScript함수는 다음과 같은 표현식으로 구현 됩니다.
$.getScript( URL );
getScript함수는 매개변수로 URL주소 만을 받습니다. 해당 URL의 JavaScript 파일을 불러 읽어 들입니다.
//script.js 파일
var entries = [{
"term": "BACCHUS. 바쿠스",
"part": "명사.",
"definition": "고대인들이 술에 취할 명분으로 편의상 만들어낸 신."
},
{
"term": "BACKBITE. 험담하다",
"part": "동사.",
"definition": "상대방에게 들킬 염려가 없을 때, 그에 관해 본 그대로를 입에담다."
},
{
"term": "BANG. 빵! 가지런한 앞머리",
"part": "명사.",
"definition": "총 쏘는 소리. 앞머리를 잘라 내린 여성의 머리모양."
}];
var html = 'getScript 함수 사용입니다.';
$.each(entries, function() {
html += '<div class="entry">';
html += '<h3 class="term">' + this['term'] + '</h3>';
html += '<div class="part">' + this['part'] + '</div>';
html += '<div class="definition">' + this['definition'] + '</div>';
html += '</div>';
});
$('#dictionary').html(html);
//dictionary.js
$(document).ready(function() {
$('#script').click(function() {
$.getScript('script.js');
return false;
});
});
위 예제 코드는 getScript 함수의 간단한 구현 예제 코드입니다. 클릭 이벤트가 발생 했을 때 script.js파일을 불러 읽습니다.
맺음말
지금까지 JavaScript 및 jQuery 라이브러리에서 ajax함수를 구현 하는 방법에 대해서 알아 보았습니다. 제가 공부하면서 알게 된 부분들을 공유 하기위해 글을 썼는데 다른 분들이 많이 봐주시면서 공감하시고 공부가 되었으면 하는 작은 바램이 있습니다. 읽어 주셔서 감사합니다.
참고 도서 및 사이트
- 윤인성 저 / “모던 웹을 위한 JavaScript jQuery 입문", 한빛미디어, 2011
- 김재훈, Ajax를 품은 jQuery , 넥스트리 홈블로그
- bestheroz ,GET, POST, HEAD, OPTIONS, PUT, DELETE, LINK, UNLINK, TRACE 메소드 네이버 블로그
- Outsider's Dev Story, GET과 POST의 차이
- http://www.okjsp.net/seq/125841