다른 분들은 어떨지 모르나 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
}
}