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 | 
invalid-file