javascript/jquery

jQuery - Ajax - crossdomain 이슈

jeeyong 2012. 2. 21. 11:44
출처:  http://igna.tistory.com/19 

jQuery 최신 버젼을 갖고 Ajax통신 기능을 이용하려고 하면 종종 직면하게 되는 이슈는 crossdomain 이슈다. crossdomain 이슈가 뭐냐고 물어보는 사람들을 위해 잠깐 설명하자면

- crossdomain 이슈사항 정리 -
1. 전제조건 
- 조건 1: 내가 보고 있는 페이지의 주소는 http://www.aaa.com 이다.
- 조건 2: http://www.aaa.com의 페이지가 http://www.bbb.com의 rest api 를 호출하여 데이터를 JSON으로 가져오려고 한다.

2. 결론
 조건 1의 내가 이용하는 페이지의 주소의 도메인과 조건 2의 데이터를 가지고 오기위한 서버의 도메인이 서로 상이할 경우 crossdomain이라고 부른다. 이러한 crossdomain은 서버 공격 및 보안 취약성을 갖게 되므로 서로 신뢰할 수 있는 경우에만 이를 허용하는 서비스를 구축하는 것이 일반적이다.

 라고 합니다.
jQuery 1.5.0 이후의 버젼부터는 이러한 crossdomain 을 원천 봉쇄해버렸다. 그래서 이런 메시지를 띄운다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$(document).ready(function(){
        loadData();
});
 
function loadData()
{
    $.ajax({
                       "apikey=947f96c9d2518613faae766eed75bca030ad67d7"
        , sucess: function( data, textStatus, jqXHR )
                  {
                      alert("success");
                  }
        , error: function( jqXHR, textStatus, errorThrown )
                 {
                    alert( textStatus + ", " + errorThrown );
                 }
    });
}

하지만 HTML과 자바스크립트로 OpenAPI를 이용한 매쉬업 컨텐츠 페이지를 만들고 싶다면 이런 crossdomain을 어떻게 처리할지. 그게 문제가 된다. 일단 여러가지 테스트 결과 jQeury에서는 "http://"부터 그 다음 "/"가 나올때까지의 도메인 문자열이 현재 보고 있는 페이지의 도메인 문자열이 상이하면 crossdomain 문제를 일으킨다.
(예를 들어 현재 블로그 주소인 igna.tistory.com과 igna1.tistory.com도 다른 도메인 취급한다.)
게다가 도메인 문자열이 동일해도 포트번호가 서로 달라도 crossdomain 문제를 일으키니 정말 답이 없다.
그런 문제들에 대해 아무리 검색해봐도 뾰족한 수가 나오는거 없이 JSONP라는 방법을 이용하라고 한다.
물론 JSONP라는 방법은 이런 crossdomain을 우회할 수 있는 하나의 "꼼수"로써 사용할만 하다.
혹시 JSONP라는 것을 정확히 모르는 분들을 위해 짧막 설명을 하자면  

 <img src="http://aaaa.com" />
 
위와 같은 html 코드가 있을 때 저 src라는 attribute가 JSONP 역할을 하는거다. 저 src속성은 어떤 도메인을 넣든 크로스도메인 이슈를 발생시키지 않으니까 저 꼼수를 이용해 크로스도메인을 처리하는 방법이 JSONP방법이다.
(좀더 자세한 내용은 : http://bob.pythonmac.org/archives/2005/12/05/remote-json-jsonp/ )

그렇다면 위에서 만든 코드를 아래와 같이 수정해보자.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
$(document).ready(function(){
    loadData();
});
 
function loadData()
{
    var data ={};
    data.q = 'test';
    data.apikey = '947f96c9d2518613faae766eed75bca030ad67d7';
    data.result = '10';
    data.output = 'json';
    data.callback = "jsonp_callback";
             
 
    $.ajax({
        url: "http://apis.daum.net/search/image"
        , crossDomain: true
        , dataType: "jsonp"
        , type: 'GET'
        , data: data
        , error: function( jqXHR, textStatus, errorThrown )
        {
            alert( textStatus + ", " + errorThrown );
        }
         
    });
}
 
function jsonp_callback( data )
{
    alert("!!!");
}

위와같이 코드를 작성하고 브라우져에서 확인하면 두가지 alert 창이 뜨는데 하나는 "!!" alert이 뜰테고 하나는 아래와 같은 창이 뜨게 된다.

 이것은 jQuery가 jsonp로 데이터를 호출하기 위해 주소 끄트머리에 붙여놓은 자동 생성 스크립트인데 그 내용을 파싱하지 못하겠다고 에러를 띄운것이다. 사실 alert코드를 심어놔서 확인할 수 있었던 것이지 alert없었어도 사실 아무런 상관이 없다. 그리고 "!!" 이 뜨는 시점에 data를 확인해보면 아래와 같이 확인할 수가 있다.

 데이터가 아주아주 순조롭게 잘 들어왔다. 저걸로 화면에 표시해주면 되겠다. 하고 생각하긴 했는데 다만 문제는 이 방법에 아주아주 큰 취약점이 있다. Error를 처리 할 수 없다는 점인데 결국 JSONP라는 방법은 꼼수에 불과하기 때문에 정석적인 방법과는 거리가 있다.
간혹 1.4 버전의 jQuery를 사용하면 되지 않느냐는 말씀을 하시는 분들이 있는데 그것은 시대에 역행하는 방법으로 문제를 해결한다는 것은 결국 정체하자는 이야기밖에 되질 않으므로 패스.
어떻게 처리하는게 좋을까 하다가 회사의 차장님의 끈질긴 연구와 검색 덕분에 알게된 해결책.
 
다음 시간에 공개합니다.