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 를 구현 하였습니다.
서버는 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) + ")";
}
}
용어가 생소한분들이 많을거라고 생각드는군요,,, 짧은 지식으로 간단히 설명히 어렵네요.