프로그램/script

jsonp springmvc example

mulderu 2012. 1. 13. 13:47
아래는 일반적인 javascript ajax 에 대한 설명이 아니라, Same origin policy를 극복하기 위한 방법을 설명 합니다.




jsonp (Json with padding)란 CrossDomain ( Same Origin Policy) 을 극복하기 위한 javascript 비동기 통신 방법을 말합니다.
javascript에서 타도메인의 url 로부터 값을 가져오는건 원천적으로는 금지 되어 있습니다.
이러한 규칙을 Same Orgigin Policy 라고 하죠,
(관련된 위키 자료 :  http://en.wikipedia.org/wiki/Same_origin_policy )


 

보통 javascript 원격호출은 XMLHttpRequest 를 이용한 Ajax Remote Call 이 일반적인 javascript 비동기 호출 방법입니다.
그러나 Origin 이 다른 경우 사용할 수 없다는 단점이 있습니다.

이러한 방법을 극복하기 위한 꼼수로 서버에 Proxy Servlet을 두고 다시 Relay하도록 하는경우도 있고
그렇지 않은 경우 이번에 제가 설명할 jsonp를 이용하는 꼼수를 이용할 수 있습니다.

왜 jsonp 가 꼼수 일까요 ???
결국은 javascript (script tag) 를 동적으로 임베딩하는겁니다.
HTTP GET Method 로 호출 하기 때문에 많은양의 데이터를 Post 하기에는 적절치 않는게 가장 큰 문제 입니다.
기타 약점으로는 에러처리가 거의 불가 하다는 점이 또 있군요...


아래 그림은 jsonp를 이용하는 구조 입니다.






아래는 멀더의 입장에서 간단하게  jsonp  를 구현 하였습니다.

서버는 spring3  mvc controller 입니다.

<script type="text/javascript">
// jsonp 구현, 2012.91.13, by Mulder 

jsonpCallbackFnc = {};

var jsonpUtil = {

    version  : 0.1,

    jsonpIdx : 0,

        callJsonp : function(url, callback, param) {

            ++ this.jsonpIdx;

            var fncName = 'fnc_'+ this.jsonpIdx;

            jsonpCallbackFnc[fncName] = callback;

            $('<script/>').attr({ type: 'text/javascript', charset: 'utf-8', src: url+'/'+fncName+'/'+param}).appendTo('head');

        }

};

$(document).ready(function() {

$('.button').button();

       

$('.button#button011').click(function() {

jsonpUtil.callJsonp('http://127.0.0.1:8080/test/jsonp/fileItem',  

function(data) {

                  alert (data.fileName);

                    }, 

                    'fileId001');

});

   

$('.button#button012').click(function() {

jsonpUtil.callJsonp('http://127.0.0.1:8080/test/jsonp/fileItem',  

                        function(data) {

                            var items = [];

        

                            $.each(data, function(key, val) {

                              items.push('<li>' + key + '=' + val + '</li>');

                            });

        

                            $('<ul/>', {

                                  html: items.join('')

                                }).appendTo('body');

                         }, 

                         'fileId001');

            });

$('.button#button013').click(function() {

                alert( '013');

            });

$('.button#button014').click(function() {

                alert( '014');

            });

});

</script>



Example Controller  

@Controller

@RequestMapping(value = "/jsonp")

public class JsonpController {

private static final Logger logger = LoggerFactory.getLogger(JsonpController.class);


@RequestMapping(value = { "/fileItem/{cb}/{fileId}" }, method = RequestMethod.GET)

@ResponseBody

public String getFileItem(@PathVariable String cb, @PathVariable String fileId, Model model)

{

  FileItemVO fileItemVO = new FileItemVO();

  fileItemVO.setFileId("thisisFileId");

  fileItemVO.setFileName("thisisFileName");

  fileItemVO.setFileSize(1024);

  model.addAttribute(cb);

  model.addAttribute(fileId);

  model.addAttribute(fileItemVO);

  return "jsonpCallbackFnc." + cb + "(" + JSonUtil.toJSon(fileItemVO) + ")";

}

 

}


용어가 생소한분들이 많을거라고 생각드는군요,,, 짧은 지식으로 간단히 설명히 어렵네요.