블로그 이미지

카테고리

데꾸벅 (194)
Publisher (39)
Scripter (97)
Programmer (1)
Designer (30)
Integrator (18)
Pattern Searcher (4)
News (2)
강좌 및 번역 (3)

최근에 올라온 글

최근에 달린 댓글

100라인 Ajax Wrapper

Scripter/AJAX / 2008. 4. 19. 15:13



다른 분들은 어떨지 모르나 UI 개발자인 데꾸벅의 경우는 프로젝트를 할때 마다 느끼는 거지만 어떤 Ajax framework를 쓸지 고민을 많이 하는 편이다.
그냥 규모가 좀 되는곳이라면 jQuery나 prototype을.. 그리고 내부 애플리케이션이라면 extjs를... 혹은 작더라도 struts2를 쓸때는 dojo를...
근데 문제가 되는것은 아주 작은 소규모 프로젝트의 경우는 이러한 ajax framework나 libraries를 사용하기가 좀 그래서 단순 XHR Wrapper를 만들어 사용한다



[데꾸벅이 사용하는 Ajax Wrapper 01]

function createHttp() {
 try {
  return new XMLHttpRequest();
 }
 catch (e) {
  var objectNames = ["MSXML2.XMLHTTP.5.0",
"MSXML2.XMLHTTP.4.0", "MSXML2.XMLHTTP.3.0",
"MSXML2.XMLHTTP", "Microsoft.XMLHTTP"];
  for (var i = 0; i < objectNames.length; i ++) {
   try {
    return new ActiveXObject(objectNames[i]);
    break;
   }
   catch (e) {
   }
  }
  return null;
 }
}


var loading = false;
function getResponse(uri,content) {
 try {
  loading = true
  var body = document.body;
  var oHttp = createHttp();
  if(uri.indexOf('?') ==-1) aux = '?';
  else aux = '&';
  oHttp.open("POST", uri + aux+"time=" + (new Date()).getTime(), false);
  if(content == undefined) {
   content = '';
  } else {
   oHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
  }
  oHttp.send(content);
  result = new Array();
  if(isSafari || isOpera) {
    resultNodes = oHttp.responseXML.firstChild.childNodes;
    for(var i=0; i';

  return false;
 }
}

function requestHttp(uri) {
 try{
  var oHttp = createHttp();
  oHttp.open("GET", uri + "&time=" + (new Date()).getTime(), false);
  oHttp.send("");
  if(isSafari || isOpera) {
   var returnValue = oHttp.responseXML.firstChild.firstChild.nextSibling.firstChild.nodeValue;
   delete oHttp;
   return returnValue;
  } else {
   var returnValue = oHttp.responseXML.selectSingleNode("/response/error").text;
   delete oHttp;
   return returnValue;
  }
 } catch (e) {
  window.status = e.messge;
 }
}

function requestHttpText(uri) {
 var oHttp = createHttp();
 oHttp.open("POST", uri + "&time=" + (new Date()).getTime(), false);
 oHttp.send("");
 var returnValue = oHttp.responseText;
 delete oHttp;
 return returnValue;
}

function requestHttpXml(uri) {
 var oHttp = createHttp();
 oHttp.open("GET", uri + "&time=" + (new Date()).getTime(), false);
 oHttp.send("");
 var returnValue = oHttp.responseXML;
 delete oHttp;
 return returnValue;
}

function requestPost(uri, content) {
 var oHttp = createHttp();
 oHttp.open("POST", uri + "&time=" + (new Date()).getTime(), false);
 oHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
 oHttp.send(content+ "&time=" + (new Date()).getTime());
 var returnValue = oHttp.responseXML.selectSingleNode("/response/error").text;
 delete oHttp;
 return returnValue;
}

function requestPostText(uri, content) {
 var oHttp = createHttp();
 oHttp.open("POST", uri + "&time=" + (new Date()).getTime(), false);
 oHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
 oHttp.send(content);
 var returnValue = oHttp.responseText;
 delete oHttp;
 return returnValue;
}


function setRequestBody(elementName, elementValue, boundary){
 var body = "";
 body += "--" + boundary + "\r\n";
 body += "Content-Disposition: form-data; name=\"" + elementName + "\"" + "\r\n\r\n";
 body += elementValue + "\r\n";
 return body;
}



[모 프로젝트에서 사용했던 예~ ]

/**
 * HTTP 혹은 HTTPS 방식의 통신을 제공하는 클래스객체를 생성합니다.
 * @class EnHttp
 *
 */
function EnHttp(){

 this.dialBack ="";    //컴포넌트와 컨테이너 인증에 사용합니다.
 this.extraInfo ="";    //Url의 추가 정보를 지정합니다.
 this.host = "127.0.0.1";  //호스트 이름을 지정합니다.
 this.method = "POST";   //메쏘드(HTTP의 Verb)를 지정합니다.
 this.optionalHeaders = "";  //HTTP요청의 추가 헤더를 지정합니다.
 this.password = "";    //패스워드를 지정합니다.
 this.port = "80";    //포트를 지정합니다.
 this.postData ="";    //POST, PUT 요청에 사용되는 데이터를 지정합니다.
 this.protocol ="HTTP";   //프로토콜을 지정합니다.
 this.proxy ="";     //프록시가 설정된 환경인 경우, 프록시설정 정보를 지정합니다.
 this.referer = "";    //HTTP요청의 Referer를 지정합니다.
 this.responseContents="";  //응답 내용 문자열을 전달합니다.
 this.responseHeaders ="";  //응답헤더 문자열을 전달합니다.
 this.responseStatusCode =""; //응답상태코드를 문자열로 전달합니다 (예: "404")
 this.responseStatusText =""; //응답상태를 문자열로 전달합니다.(예: "Not Found")
 this.ssl = false;    //SSL 사용여부를 지정합니다.
 this.timeout = 0;    //HTTP요청의 timeout을 지정합니다.
 this.urlPath="";    //경로를 지정합니다.
 this.user ="";     //사용자 이름을 지정합니다.
 this.version ="";    //HTTP버전 문자열을 지정합니다.
 this.url = "";     //전체 URL을 지정 합니다.


 /**
  * 실제 HTTP요청을 서버에 전송합니다.
  * @return true/false
  */
 this.SendRequest = function(){
  this.url = this.protocol + "://"+ this.host + ":" + this.port + this.urlPath;

  var xmlhttp = createHttp();
  xmlhttp.open(this.method, this.url,false);

  var headers = this.optionalHeaders.split("\r\n");
  for(var i=0; i < headers.length; i++){
   var oneHeaders = headers[i].split(":");
   xmlhttp.setRequestHeader(oneHeaders[0],oneHeaders[1]);
  }


  var varResponseStatusCode = "";
  var varResponseHeaders = "";
  var varResponseContents = "";

     //도착하는 이벤트 핸들러 걸어주고
     xmlhttp.onreadystatechange = function() {
         if (xmlhttp.readyState==4) {
    varResponseStatusCode = xmlhttp.status;
    varResponseHeaders = xmlhttp.getAllResponseHeaders();
             if (xmlhttp.status==200) {
     varResponseContents = xmlhttp.responseText;
    }
         }
     }
     xmlhttp.send(this.postData);
  this.responseStatusCode = varResponseStatusCode;
  this.responseHeaders = varResponseHeaders;
  this.responseContents = varResponseContents;
 }


 /**
  * 쿠키를 읽어옵니다.
  * @param {Object} url - 쿠키를 읽어올 Url주소
  * @return Cookie
  */
 this.getCookie = function(url){

 }

 /**
  * 쿠키를 설정합니다.
  * @param {Object} url- 쿠키를 설정할 Url주소.
  * @param {Object} cookie- 설정할 쿠키.
  * @return ture@false
  */
 this.setCookie = function(url,cookie){

 }


 /**
  * 파일을 form 형태로 업로드합니다.
  * @param {Object} file- 업로드할 파일명(경로).
  * @param {Object} url- 업로드할 경로.
  */
 this.upload = function(file,url){

}
}


Kris Zyp's 블로그에 Future Ajax Wrapper라는 포스트에서 cross-browser와 cross-domain을 지원하는 100라인 짜리 ajax wrapper 소스를 선보였다.

W3C에서 제안한 cross-site acess 를 사용하는 대신에 IE8의 XDR(XDomainRequest)와 새로운 cross-site request를 추가하였다고 한다. 이번에 출시된 IE8은 표준을 모두 따른다고 하더니만....   또다시 IE8용으로 분기를 해줘야 한다.. ㅡ.,ㅡ;



function doRequest(method,url,async,onLoad,onProgress) {
    var xhr;
    if ((onProgress || isXDomainUrl(url)) && window.XDomainRequest) {
         if (url.match(/^https:/) && !onProgress) {
            loadUsingScriptTag(url); 

            return;
	}
        xhr = new XDomainRequest;
	if (!url.match(/^http:/)) {
            url = absoluteUrl(location.href,url);

          }
	if (!(method == “GET” || method == “POST”)) {
	    url += “&method=” + method;
	    method = “POST”;
	}
	function xdrLoad() {
	   if (xhr.contentType.match(/\/xml/)){
		var dom = new ActiveXObject(”Microsoft.XMLDOM”);
		dom.async = false;
		dom.loadXML(xhr.responseText,200);
		onLoad(dom);
	   }
	   else {
	   	onLoad(xhr.responseText,200);
	   }
	}
	if (async === false) {
	    var loaded;
	    xhr.onload = function() {
		loaded = true;
		xdrLoad();
	    }
            xhr.open(method,url);
	    xhr.send(null);
	    while(!loaded) {
		alert(”결과를 기다리는 중입니다.”);
	    }
 	    return;
	}
	else {	// do an asynchronous request with XDomainRequest
            xhr.onload = xdrLoad;
            xhr.open(method,url);
            xhr.onprogress = onProgress;
	}
    }

    else {
        xhr = new XMLHttpRequest; 
        xhr.open(method,url,async);
        xhr.onreadystatechange = function() {
            if (xhr.readyState == 3) 
                onProgress(xhr.responseText);
            if (xhr.readyState == 4) // finished
                onLoad(xhr.responseText,xhr.status);
        }
    }
    xhr.send(null); 


	function absoluteUrl : function(baseUrl, relativeUrl) {
		if (relativeUrl.match(/\w+:\/\//))
			return relativeUrl;
		if (relativeUrl.charAt(0)==’/') {
			baseUrl = baseUrl.match(/.*\/\/[^\/]+/)
			return (baseUrl ? baseUrl[0] : ”) + relativeUrl;
		}
		baseUrl = baseUrl.substring(0,baseUrl.length - baseUrl.match(/[^\/]*$/)[0].length);
		if (relativeUrl == ‘.’)
			return baseUrl;
		while (relativeUrl.substring(0,3) == ‘../’) {
			baseUrl = baseUrl.substring(0,baseUrl.length - baseUrl.match(/[^\/]*\/$/)[0].length);
			relativeUrl = relativeUrl.substring(3);
		}
		return baseUrl + relativeUrl;
	}
	function loadUsingScriptTag(url) {
		… do JSONP here if we want
	}
}

'Scripter > AJAX' 카테고리의 다른 글

Ajax Framework 분석  (0) 2009.05.04
CSSHttpRequest  (0) 2008.11.12
HTTP Header에 대하여  (0) 2008.11.08
AJAX에서 즐겨찾기와 뒤로가기를 다루는 방법  (0) 2008.09.24
어떤 AJAX Framework를 선택할 것인가.  (0) 2008.03.14
Post by 넥스트리소프트 데꾸벅(techbug)
, |