우선 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의 문제를 가지고 있던 코드를 내부 페이지를 호출하도록 변경...

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

<button onclick="getNewID()">새 아이디 얻기</button>

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("&amp;");
    }

    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 호출
크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by Heart