본문 바로가기

front

ajax crossdomain

-퍼옴- jsonp는 기본적으로 post방식을 지원하지 않는것 같음.

=======================================================================

일단 몇가지 문서들을 봐야만 했는데  jQuery.ajaxPrefilter() 부분이었다. 이 ajaxPrefilter() 메서드는 ajax의 low-level 메서드로 jQuery를 통해 ajax통신을 하게 될때 콜백함수로 호출되어 통신을 위한 밑작업들을 수행하게 되는데 cross-domain또한 이 메서드 중간에서 차단하여 막는것도 여기서 처리하게된다. 이 사실을 어떻게 알았냐면 Extending Ajax: Prefilters, Converters, and Transports 라는 문서를 보고 나서 알게 되었다.

이 문서에 따르면 이 기능(?)들은 jQuery 1.5 .$ 버젼부터 지원하기 시작한 것으로 ajax 요청의 "보내기", "받기", 그리고 "관리하기"에 관련된 내용을 담당한다고 설명되어있다.

Exteding ajax : Prefilters, Converters, and Transports

    As of jQuery 1.5, $.ajax() provides three means to extend its functionalities for sending, receiving, and     managing ajax requests:


일단 여러가지로 우리가 봐야할 것은 보낼 때 cross-domain을 막는 부분을 해결해야 하므로 보내는 쪽 담당인 Prefilters 부분을 살펴보도록 하자.
Prefilters는 ajax의 옵션처리, 호출등을 담당하는데 실제 소스 코드를 확인해보면 다음과 같다.
 

1
2
3
4
$.ajaxPrefilter( function( options, originalOptions, jqXHR )
{
  // Modify options, control originalOptions, store jqXHR, etc
});

 
각 파라미터의 설명들이 있는데 내용은 다음과 같다.

  • options : 요청을 보내는 옵션들  
  • originalOptions : ajaxSettings에서 기본적으로 수정되어지지 않는 ajax 메서드에서 제공되는 옵션들. 
  • jqXHR : jQuery HTTP Request

이렇게 되며 이 메서드를 Extending해주면 ajax통신을 manual 하게 셋팅할 수 있는데 그 내용중에서 아래의 내용을 확인해 볼 것.

Prefilters can also be used to modify existing options. For example, the following proxies cross-domain requests through http://mydomain.net/proxy/:

이 이야기는 무슨 이야기냐 하면 기존의 옵션을 수정할 수 있다면서 프록시서버를 통해 크로스도메인 요청을 보낼수 있다는 이야기를 하며 아래의 코드를 소개해 놓았다.

1
2
3
4
5
6
7
8
$.ajaxPrefilter( function( options )
{
  if ( options.crossDomain )
 {
    options.url = "http://mydomain.net/proxy/" + encodeURIComponent( options.url );
    options.crossDomain = false;
  }
});

그럼 우리가 유추해볼 수 있는건 다음과 같다.

  1. 통신을 하기전엔 무조건 $.ajaxPrefilter()를 거친다.
  2. ajaxPrefilter() 내부를 변조해 처리하면 cross-domain도 통과할 수 있다. 

라는 것인데 그래서 여태껏 "jQuery ajax crossdomain" 이라는 검색어로 검색하던 것을 "jQuery ajaxPrefilter crossdomain"으로 바꿔 검색해봤다. 그랬더니 서광처럼 등장한 "http://craveytrain.com/posts/cors" 페이지.
여기에 등장한 소스 코드는 

1
2
3
$.ajaxPrefilter('json', function(options, orig, jqXHR) {
    if (options.crossDomain && !$.support.cors) return 'jsonp'
});

이것인데 이 소스를 적용해 테스트 해봤더니 인터넷 익스플로러에선 되고 크롬에선 안되고 하는 크로스브라우징 문제가 발생했는데 이걸 어쩐다.. 하고 고민하다가 어차피 그냥 통신 자체를 'jsonp'로 속여서 내보내면 해결될 문제라고 생각해 아래와 같이 수정했다.

1
2
3
$.ajaxPrefilter('json', function(options, orig, jqXHR) {
    return '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';
 
    $.ajaxPrefilter('json', function(options, orig, jqXHR) {
        return 'jsonp';
    });
  
    $.ajax({
        url: "http://apis.daum.net/search/image"
        , crossDomain: true
        , dataType: "json"
        , type: 'GET'
        , data: data
        , success: function( data, textStatus, jqXHR )
        {
            alert("sccess : " + data.channel.item.length );
        }
        , error: function( jqXHR, textStatus, errorThrown )
        {
            alert( textStatus + ", " + errorThrown );
        }
    });
}

이렇게 ajax 통신하기 전에 ajaxPrefilter를 수정해주면 해결이 된다.