X-Git-Url: http://git.osdn.jp/view?a=blobdiff_plain;f=0.6.x%2Fjs%2F06_net%2F02_XNetJSONP.js;h=3fbcf778e5bf54db9209b2d56055e28805276611;hb=20c3a948b20e52efc28fd103fc075d787c6d65d2;hp=13bd9e528211ff7dcb4c80704254252fad9c5008;hpb=7f26e99d39211b5749c4ad62a84855404c7390a3;p=pettanr%2FclientJs.git diff --git a/0.6.x/js/06_net/02_XNetJSONP.js b/0.6.x/js/06_net/02_XNetJSONP.js index 13bd9e5..3fbcf77 100644 --- a/0.6.x/js/06_net/02_XNetJSONP.js +++ b/0.6.x/js/06_net/02_XNetJSONP.js @@ -1,3 +1,5 @@ +//{+jsonp"jsonpによるajax"(jsonpによるクロスドメイン通信。)[+net,+ninjaiframe] + /* * Operaでも非同期リクエストが並列処理できる img-JSONP * http://developer.cybozu.co.jp/takesako/2007/06/opera_img-jsonp.html @@ -16,180 +18,206 @@ * * IE6(IETester,localhost) で動かない, * - * TODO postMessage + * TODO iframe 内を他ドメインにして jsonp のセキュリティを強化。他ドメインに jsonp を読み込んで 正しい JSON か?検証後にフレーム間通信で戻す。 */ -X.Net.JSONP = { - cb : function( accessKey, jsonString, time, opt_json2FileSize ){ + // TODO chashe + // TODO iframe useful or not. TODO check dynamicIframe + // TODO file: では http: は使えない + +X[ 'Net' ][ 'JSONP' ] = { + 'cb' : function( accessKey, jsonString, time, opt_json2FileSize ){ if( accessKey !== X_NET_JSONP_ACCESS_KEY || !X_NET_JSONPWrapper._busy ) return; X_NET_JSONPWrapper._busy = false; X_NET_JSONPWrapper - .asyncDispatch( 0, { - type : jsonString ? X.Event.SUCCESS : X.Event.ERROR, - data : jsonString //eval( jsonString ) + [ 'asyncDispatch' ]( { + type : jsonString ? X_EVENT_SUCCESS : X_EVENT_ERROR, + response : X_String_parseTrustedJsonString( jsonString ) } ); + X_Net_JSONP_errorTimerID && X_Timer_remove( X_Net_JSONP_errorTimerID ); + console.log( 'ms : ' + time + ' speed : ' + ( ( jsonString.length + ( opt_json2FileSize || 0 ) ) / time * 1000 ) + ' バイト/秒.' ); } }; var X_NET_JSONP_ACCESS_KEY = Math.random(), - X_NET_JSONP_NinjaIframe; - - -function X_NET_JSONP_loadScriptInNinjaIframe( url ){ - var json2Path = 'js/libs/json2.js', - json2FileSize = 18103, - html; + X_Net_JSONP_maxOnloadCount, - X_NET_JSONP_NinjaIframe || ( X_NET_JSONP_NinjaIframe = new X.Util.NinjaIframe() ); + X_Net_JSONP_onloadCount = 0, - // TODO ' 化 恐らくアンチウイルスソフトが反応しないための対策 + X_Net_JSONP_errorTimerID; + +X_TEMP.X_NET_JSONP_init = function(){ + X_NET_JSONPWrapper = X_Class_override( X[ 'Util' ][ 'NinjaIframe' ](), X_TEMP.X_NET_JSONP_params ); - if( X_UA.IE8 ){ - html = [ - // http://blog.livedoor.jp/dankogai/archives/51503830.html - // Ajax - IE8にもJSON入ってます。使えるとは限らないけど - // Compatibility mode (別名Quirks mode) では、JSONオブジェクトは無効になります。iframeもだめです - /* 以下のコードは XP ie8 では動くけど、win8 IE11(8モード)で動かない 開発の便宜を取って,setTimeout を挟む - '', - '' */ - '', - '' - ]; - } else - if( X_UA.IE9 ){ - html = [ - '', - '' - ]; - } else - if( window[ 'JSON' ] ){ - html = [ - '', - '' - ]; - } else - if( X_UA.IE4 || X_UA.MacIE ){ - html = [ - '', - '', - '' - ]; - } else - if( X_UA.IE < 8 ){ // ie5-7 - html = [ - '', - '', - '' - ]; - } else { - html = [ - '', - '', - '' - ]; - }; + delete X_TEMP.X_NET_JSONP_init; + delete X_TEMP.X_NET_JSONP_params; - X_NET_JSONP_NinjaIframe - .refresh( html.join( '' ) ) - .listen( [ X.Event.SUCCESS, X.Event.ERROR ], X_NET_JSONPWrapper, X_NET_JSONP_iframeListener ); + return X_NET_JSONPWrapper; }; +X_TEMP.X_NET_JSONP_params = { + + _busy : false, + _canceled : false, + + load : function( option ){ + //createURL + var url = option[ 'url' ], + params = option[ 'params' ], + callback = option[ 'callbackName' ], + charset = option[ 'charset' ], + json2Path = window.RegExp ? 'js/libs/json2.js' : 'js/libs/json2_regfree.js', + json2FileSize = 18103, + html; + + url = X_URL_create( url, params ); + + if( !callback && !( callback = X_URL_ParamToObj( url.split( '?' )[ 1 ] )[ 'callback' ] ) ){ + url += '&callback=cb'; + callback = 'cb'; + }; + + charset = charset ? ' charset="' + charset + '"' : ''; + + // TODO ' 化 恐らくアンチウイルスソフトが反応しないための対策 + // document.postMessage()→window.postMessage() (Opera 9.50 build 9841 -) + // http://d.hatena.ne.jp/cnrd/20080518/1211099169 + // 最近の仕様変更(引数のtargetOriginとかMessageEventのoriginとか)にはまだ対応してないみたい + + if( X_UA[ 'Opera' ] ){ + html = [ + ( window[ 'JSON' ] ? '' : '' ), + '', + '', + '' + ]; + X_Net_JSONP_maxOnloadCount = 2; + } else + if( X_UA[ 'IE8' ] ){ + html = [ + '', + '' + + /* 以下のコードは XP ie8 では動くけど、win8 IE11(8モード)で動かない 開発の便宜を取って,setTimeout を挟む + '', + '' */ + ]; + X_Net_JSONP_maxOnloadCount = 2; + } else + if( X_UA[ 'IE9' ] ){ + html = [ + '', + '' + ]; + X_Net_JSONP_maxOnloadCount = 2; + } else + if( window[ 'JSON' ] ){ + html = [ + '', + '' + ]; + X_Net_JSONP_maxOnloadCount = 1; + } else + if( X_UA[ 'IE4' ] || X_UA[ 'MacIE' ] ){ + html = [ + '', + '', + '' + ]; + X_Net_JSONP_maxOnloadCount = 3; + } else + if( X_UA[ 'IE' ] < 8 ){ // ie5-7 + html = [ + '', + '', + '' + ]; + X_Net_JSONP_maxOnloadCount = 3; + } else { + html = [ + '', + '', + '' + ]; + X_Net_JSONP_maxOnloadCount = 2; + }; + + X_NET_JSONPWrapper + [ 'refresh' ]( html.join( '' ) ) + [ 'listen' ]( [ 'ninjaload', 'ninjaerror' ], X_NET_JSONP_iframeListener ); + + X_NET_JSONPWrapper._busy = true; + }, + + cancel : function(){ + X_NET_JSONPWrapper.reset(); + X_NET_JSONPWrapper._canceled = true; + }, + + reset : function(){ + X_NET_JSONPWrapper._busy = X_NET_JSONPWrapper._canceled = false; + X_NET_JSONPWrapper[ 'unlisten' ]( [ 'ninjaload', 'ninjaerror' ], X_NET_JSONP_iframeListener ); + X_NET_JSONPWrapper[ 'refresh' ]( '' ); + X_Net_JSONP_errorTimerID && X_Timer_remove( X_Net_JSONP_errorTimerID ); + X_Net_JSONP_errorTimerID = X_Net_JSONP_onloadCount = 0; + } + }; function X_NET_JSONP_iframeListener( e ){ switch( e.type ){ - case X.Event.SUCCESS : - console.log( 'iframe onload' ); - + case 'ninjaload' : + console.log( 'iframe onload, but ' + X_Net_JSONP_onloadCount + ' < ' + X_Net_JSONP_maxOnloadCount ); + if( ++X_Net_JSONP_onloadCount < X_Net_JSONP_maxOnloadCount ) return; + + // TODO callback が無ければ error -> timeout を観る? + X_Net_JSONP_errorTimerID = X_NET_JSONPWrapper[ 'asyncDispatch' ]( 1000, X_EVENT_ERROR ); break; - case X.Event.ERROR : + case 'ninjaerror' : console.log( 'iframe onerror' ); - X_NET_JSONPWrapper.asyncDispatch( 0, X.Event.ERROR ); - break; - }; -}; - - -X_NET_JSONPWrapper = X_Class_override( - new X.EventDispatcher(), - { - - _operaImage : null, // X.Net.Image(); - _busy : false, - _canceled : false, - - load : function( url, data, timeout ){ - //createURL - if( X_NET_JSONP_operaImageHandleEvent ){ - this._operaImage = X.Net.Image( url, false ) - .listenOnce( [ X.Event.SUCCESS, X.Event.ERROR, X.Event.TIMEOUT ], X_NET_JSONP_operaImageHandleEvent ); - } else { - X_NET_JSONP_loadScriptInNinjaIframe( url ); - }; - - this._busy = true; - }, - - cancel : function(){ - if( this._operaImage ){ - this._operaImage - .unlisten( [ X.Event.SUCCESS, X.Event.ERROR, X.Event.TIMEOUT ], X_NET_JSONP_operaImageHandleEvent ) - .cancel(); - delete this._operaImage; - } else { - this._canceled = true; - }; - }, - - reset : function(){ - this._busy = this._canceled = false; - } - } -); - -function X_NET_JSONP_operaImageHandleEvent( e ){ - switch( e.type ){ - case X.Event.SUCCESS : - case X.Event.ERROR : - X_NET_JSONP_loadScriptInNinjaIframe( e.src ); - break; - case X.Event.TIMEOUT : - X_NET_JSONPWrapper._operaImage - .unlisten( [ X.Event.SUCCESS, X.Event.ERROR, X.Event.TIMEOUT ], X_NET_JSONP_operaImageHandleEvent ) - .reset(); - X_NET_JSONPWrapper.asyncDispatch( 0, X.Event.ERROR ); + X_NET_JSONPWrapper[ 'asyncDispatch' ]( X_EVENT_ERROR ); break; }; + return X_Callback_UN_LISTEN; }; -if( !X_UA.Opera ) X_NET_JSONP_operaImageHandleEvent = null; \ No newline at end of file