본문 바로가기

개발자이야기/JavaScript이야기

eval.call

반응형

몇 번의 글에 걸쳐서 AJAX 의 일반적인 사용방법에 대해 알아보고 기본적인 구성을 해보았다. 오늘은 지난시간까지 사용해본 XMLHttpRequest 의 객체를 정리해 보자. 우선 위의 첨부파일을 열어보면 sample.php 에 간단한 사용법을 볼 수 있다. myAjax.js 는 지금까지 작성해본 함수들을 정리해 보았다. 사실 최근의 AJAX 관련 라이브러리들도 이와 비슷한 방법으로 작성되고 있다. 최대한 이해하기 쉽도록 구성해 보았다. 하나하나 살펴보자.

var HTTP = {};

역시 전역에서 사용할 수 있도록 네임스페이스를 미리 만들어 둔다. 임의의 이름으로 설정해도 된다.

HTTP.request = function( /* method,url,data,callback,datakind,async,timeout,onSuccess,dummy */ args ) {

실제로 인자를 넘겨받아서 사용되는 부분인데 왜 이런 주석처리가 필요하고 args 라는 인자로 통합했는지 잠시 보자.

HTTP.request(method,url,data,callback,datakind,async,timeout,onSuccess,dummy);

위와 같이 일일히 인자를 일일히 정의하고 함수 내에서 각각의 것들을 구성하려면 꽤 어려운 일이 된다. 혹시라도 함수내에서 callback 이란 용어를 겹쳐서 사용하게 된다면 문제가 되겠다. 따라서 인자를 객체로 넘겨주고 함수내에서 객체의 name 을 빌려와서 사용하게 된다.

예) args.method

이런 방식으로 함수내에서 인자를 처리하면 네이밍이 뒤섞일 가능성이 적어지겠다.


if(!o) {

return '';

} else {

var r = [];

for(var i in o) {
r.push( i + '=' + encodeURIComponent( o[i] ) );
}

return r.join('&');

}

};

역시 지난 시간에 설명했던 데이터로 넘겨줄 부분에 대한 직렬화이다.

var getXMLHttp = function() {

if(typeof XMLHttpRequest == 'undefined') {

return new ActiveXObject(navigator.userAgent.indexOf('MSIE 5') >= 0 ? 'Microsoft.XMLHTTP' : 'Msxml2.XMLHTTP');

} else {

return new XMLHttpRequest();

}

};

XMLHttpRequest 객체의 생성 부분이다.

var dataParser = function(data, kind) {

var contentType = data.getResponseHeader('content-type');
if( (contentType && contentType.indexOf('xml') >= 0) || kind == 'xml') {

return data.responseXML;

} else {

if(kind == 'script') {

eval.call(window, data.responseText);

} else if(kind == 'json') {

return eval(data.responseText);

} else {

return data.responseText;

}

}

};

이 부분은 리턴받는 데이터를 통합적으로 parse하는 부분인데 전달인자 중 datakind 에 따라 리턴값을 조절하게 된다. eval.call(window, data.responseText); 이부분은 datakind 를 script 로 설정했을 때 실행하게 되는 부분인데 앞의 목록 글 중 call 과 apply 에 대한 설명을 참조하자. 간단하게 설명하자면 call 은 특수하게 사용되는 메서드인데 전달인자는 객체와 데이터를 포함하며 객체를 전달받으면 이 객체의 메서드로 함수를 실행하게 된다.

eval.call(window, data);
window.eval(data);

이와 같은 의미가 성립되는데 전역으로 eval 한 data 를 실행하게 된다.

var myArgs = {

method : args.method.toLowerCase() || 'post',
url : args.url || '',
data : serialize( args.data ) || '',
callback : args.callback || '',
datakind : args.datakind || '',
async : args.async || true,
responseCheck : 1,
responseTime : args.timeout || 5000,
setTimer : null,
onSuccess : args.onSuccess || function() {},
dummy : args.dummy || ''

};

전달인자들을 정리해서 사용하기 편하도록 객체에 담는 부분이다.

var dummy = function(check) {
if(check == true) {
var time = new Date();
return time.getTime();
} else {
return '';
}
}

이 부분은 전달인자 중 dummy : true 인 경우 실행하게 되는데 IE 와 같이 간혹 캐시의 문제가 발생하는 경우를 방지하기 위해서 옵션으로 두었다. 매번 같은 url 을 호출하는 경우 문서가 캐시되어서 실제 리턴 받는 값을 인식하지 못하는 경우를 자주 묻곤 하는데 이런 경우 사용하면 된다. 나머지 부분들은 이미 설명이 된 부분들이다.

sample.php 와 함께 모든 파일들을 서버에 올려두고 테스트해 보자.

첨부파일의 내용 중 HTTP.get 과 HTTP.load 는 추가로 설명하지 않아도 조금 살펴보면 쉽게 알 수 있는 부분이다. 기존에 HTTP.request 메서드를 이용하는 것이며 좀 더 축약형으로 편하게 사용할 수 있도록 정리를 한 것이다. 예제도 함께 첨부되어 있으니 참고하면 되겠다.

반응형