Aug 04
ASP로 AJAX & Cross Domain 해결하기
우선 AJAX 개념이 필요하다면 아래 포스트들을 참조…
@ Head Rush Ajax / 동기 & 비동기 + AJAX 기본 흐름
@ ASP + AJAX Step 1 / Step 2 / Step 3
ASP 사이트에서 IIS 외의 웹 서버에서 AJAX 요청을 수행하려고 했지만, Cross Domain 정책에 막혀 실패했다.
구글링을 열심히 해 본 결과, 몇 가지 방법을 찾을 수 있었다. (방법들이 깔끔하게 요약된 포스트가 있어서 링크한다.)
그 중에 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 을 해결하는 포스트가 있긴 한데 테스트는 못해봤음.
