Aug 04

ASP로 AJAX & Cross Domain 해결하기

분류: Tip.Tech 태그: ,, , Heart @ 10:34 오후

Trackback : http://dev.heartsavior.net/archives/170/trackback/

우선 AJAX 개념이 필요하다면 아래 포스트들을 참조…

@ Head Rush Ajax / 동기 & 비동기 + AJAX 기본 흐름
@ ASP + AJAX Step 1 / Step 2 / Step 3

ASP 사이트에서 IIS 외의 웹 서버에서 AJAX 요청을 수행하려고 했지만, Cross Domain 정책에 막혀 실패했다.

구글링을 열심히 해 본 결과, 몇 가지 방법을 찾을 수 있었다. (방법들이 깔끔하게 요약된 포스트가 있어서 링크한다.)

@ Cross Domain Ajax: a Quick Summary

그 중에 Web Proxy 를 사용하기로 결정!
가장 쉬워보였고, 무엇보다 야후 개발자 네트워크에 설명되어 있어서…;;
야후 OpenAPI 를 이런 식으로 사용하길 권장하는 것이니 괜찮은 방법일 것으로 보인다.

@ Use a Web Proxy for Cross-Domain XMLHttpRequest Calls - Yahoo! Developer Network

위의 포스트에는 PHP 로 proxy 를 만들어서 쓰고 있는데, ASP 사이트이기 때문에 ASP 로 proxy 를 만들어 보려 했지만 결국 실력이 딸려 프로그래밍 갤러리에 약간의 도움을 받고(도움 요청글) 코드를 정리해서 완성했다.
(JSP로는 껌일 것 같은데 ASP는 전혀 모르겠다… ‘어플 프로그래머니까…’ 라는 핑계를…-_-;; )

먼저 내가 갖고 있었던, Cross-Domain의 문제를 가지고 있던 코드를 내부 페이지를 호출하도록 변경…

<html>
	<head>
		<title>AJAX TEST - FROM SimpleHttpServer</title>
 
		<script>
			function newXMLHttpRequest() {
				var xmlreq = false;
 
				// IE가 아닌 브라우저
				if(window.XMLHttpRequest) {
					xmlreq = new XMLHttpRequest();
 
				} 
				// IE
				else if(window.ActiveXObject) {
					try {
						// 최근 IE
						xmlreq = new ActiveXObject("Msxml2.XMLHTTP");
					} catch(e1) {
						try {
							// 예전 IE
							xmlreq = new ActiveXObject("Microsoft.XMLHTTP");
 
						} catch(e2) {
							// ALL FAILED !!
						}
					}
				}
 
				return xmlreq;
			}
 
			function getNewID() {
				var req = newXMLHttpRequest();
 
				// CALLBACK 메소드로 getReadyStateHandler를 등록
				var handlerFunction = getReadyStateHandler(req, showNewID);
				req.onreadystatechange = handlerFunction;
 
				// 첫번째 파라미터 - 방식(GET or POST)
				// 두번째 파라미터 - 주소
				// 세 번째 파라미터 - 비동기 여부(true가 비동기, false는 동기)
				req.open("GET","veoh.asp",true);
 
				// POST 이면 헤더도 바꿈
				/*
				req.setRequestHeader("Content-type", 
					"application/x-www-form-urlencoded");
				*/
 
				// 쿼리 스트링이 있을 경우 파라미터로 작성
				req.send(null);
 
			}
 
			function getReadyStateHandler(req, responseJSONHandler) {
				return function() {
					// AJAX에서 데이터를 완전히 얻어온 상태
					if(req.readyState == 4) {
						// 웹 서버에서 코드 200(성공) 을 리턴하였음
						if(req.status == 200) {
							// TEXT(JSON) DATA 가 req.responseText에 들어 있음
 
							// responseJSONHandler 파라미터로 넘어온 함수를 호출
							responseJSONHandler(req.responseText);
 
						} else {
							alert("HTTP error: " + req.status);
						}
					}
				}
			}
 
			// 실제 처리가 이루어지는 함수
			function showNewID(idJSON) {
				// JSON 문자열이 비었으면 에러
				if( idJSON == null ) {
					alert("idJSON is null!!");
					return;
				}
 
				alert(idJSON);
 
				// 일반 문자열에서 JSON으로 변환
				var jsonObject = eval('(' + idJSON + ')');
 
				// error 프로퍼티를 얻음
				var error = jsonObject.error;
 
				if( error == null ) {
					alert("JSON Parse Failed!!");
					return;
 
				} 
				// 성공할 경우 에러 코드 0, 실패할 경우  > 0을 넣어놓도록 되어 있음
				else if( error > 0 ) {
					alert("ERROR Returned!! Error Code : " + error);
					return;
				}
 
				// ID 프로퍼티를 얻음
				var id = jsonObject.ID;
 
				if( id == null ) {
					alert("JSON Parse Failed!!");
					return;
				} else {
					// 얻어온 ID값을 출력
					alert("ID Received!! ID : " + id);
				}
			}
		</script>
 
	</head>
 
	<body>
	<button onclick="getNewID()">새 아이디 얻기</button>
	</body>
</html>

AJAX로 내부 사이트의 proxy 페이지를 호출하며, proxy 페이지로 veoh.asp 를 사용한다.
veoh.asp 에서 외부 사이트의 내용을 넘겨주기만 하면 된다.
Cross-Domain 을 위한 ASP Proxy 페이지(veoh.asp) 는 아래와 같다.

<% @LANGUAGE="JSCRIPT" CODEPAGE="65001" %>
<%
	// Custom Functions
	function $_GET(values) {
		return Request.QueryString(values)!="undefined"?String(Request.QueryString(values)):null;
	}
 
	function echo(values) {
		Response.Write(values);
	}
 
	// Define Timeout Limit
	Server.ScriptTimeout = 10;
 
	Object.prototype.toParam = function(){
		var querystring = [];
		for (var inc in this) {
			if(!this.hasOwnProperty(inc)) continue;
			if (this[inc]!=null) {
				querystring.push(inc + "=" + Server.URLEncode(String(this[inc])));
			} else {
				querystring.push(inc + "=");
			}
		}
 
		return querystring.join("&");
	}
 
	var xmlHTTP = Server.CreateObject("MSXML2.ServerXMLHTTP");
 
	// 원래 AJAX 요청을 수행하려던 페이지를 호출한다
	xmlHTTP.open("GET", "http://www.example.com/idrequest", false); //, false, false);
 
	xmlHTTP.setRequestHeader("Content-type", "text/xml");
	xmlHTTP.setRequestHeader("Cache-control","no-cache");
 
	xmlHTTP.send();
 
	Response.Write(xmlHTTP.responseText);
 
	xmlHTTP = null;
%>

이렇게 하면 잘 된다. 흐흐… 문제는, 디버깅이 엄청 어려울 것으로 예상된다는거… 서버를 꺼놓고 테스트해보니까 404가 아닌 500 이 리턴됐고, 더 중요한 것은 exception catch 가 안된다 -_-;;

ps. 프로토타입(prototype.js) 으로 Cross Domain 을 해결하는 포스트가 있긴 한데 테스트는 못해봤음.

@ [PrototypeJS] Cross Domain상의 Ajax 호출

Leave a Reply