Sep 062012
 

웹 페이지에서 서버로 부터 빠른 데이타를 수신하기 위해서 AJAX(Asynchronous JavaScript and XML)가 아닌 JSON(JavaScript Object Notation)을 많이 사용하게 된다.
보안에 문제가 발생할수도 있지만, 동일 도메인이 아닌 다른 서버로 부터 JSON 데이타를 빠르게 수신해서 처리하는 경우에 JSONP(JSON with padding)를 사용하면, 1개의 데이타를 다양한 웹서비스에서 활용이 가능하다.

원리는 아래와 같이 HTML에서 head에 JavaScript를 append 해서 해당 배열을 가져와서 처리하는 방식으로 처리를 한다.

이렇게 하면 문제는 동기화 방식으로 동작을 하기 때문에 순차적으로 데이타를 전달받게 되므로, 아래의 소스와 같이 재요청시 기존에 동작중인 쿼리를 모두 취소를 해버리면 비동기 방식의 데이타 수신이 가능하다.

데이타는 queue를 만들어서 데이타를 순차적으로 처리를 하면 하지만, 간혹 queue에 빠졌지만, callback이 여러번 발생될 경우도 있다. 이런 경우만 callback 함수에서 추가 처리만 해주면 다양한 브라우저에서 사용이 가능한 JSONP 라이브러리가 완성이 된다.

Sencha 로 프로젝트를 진행하다가 처음에 그냥 웹에 있는 소스를 참고해서 사용하다가 원하는 대로 동작을 하지 않아서 소스를 파악하고, 처리 방식을 나름대로 제정리를 해봤습니다.

참조URL: http://www.tomdupont.net/2010/12/extuxjsonp-v20.html

 
Ext.ns('Ext.ux');
Ext.ux.JSONP = (function () {
        var _queue = [];
        var _clearQueue = function () {
                if(_queue.length==0) { return; }
 
                while(_queue.length) {
                        var _current = _queue.shift();
 
                        try {
                                document.getElementsByTagName('head')[0].removeChild(_current.script);
                        } catch(err) { ; }
                }
        };
        var _lastCallback;
 
        return {
                request: function (url, o) {
                        if (!url) { return; }
 
                        o.params = o.params || {};
                        if (o.callbackKey)
                                o.params[o.callbackKey] = 'Ext.ux.JSONP.callback';
 
                        var params = Ext.urlEncode(o.params);
                        var script = document.createElement('script');
                        script.type = 'text/javascript';
                        script.charset = 'utf-8';
                        script.src = url + '?' + params;
 
                        _lastCallback = o.callback;
 
                        _clearQueue();
                        _queue.push({
                                url: url,
                                script: script,
                                callback: o.callback || function () { },
                                scope: o.scope || window,
                                params: params || null
                        });
 
                        document.getElementsByTagName('head')[0].appendChild(script);
                },
                callback: function (json) {
                        var _current = _queue.shift();
                        if (_current == null) {
                                _lastCallback.apply(window, [json]);
                                return;
                        }
 
                        try {
                                document.getElementsByTagName('head')[0].removeChild(_current.script);
                        } catch(err) { ; }
 
                        _current.callback.apply(_current.scope, [json]);
                }
        }
})();

팁으로 한글 Internet Explorer 9 에서 가끔 JavaScript를 로딩할때 배열에 있는 한글이 깨지는 경우가 발생한다.
이러한 문제를 해결하기 위해서 charset 을 꼭 선언하여 사용하는 것이 효과적이다.

Plugin from the creators of Brindes :: More at Plulz Wordpress Plugins