1 /** 2 * @fileOverview use flash to accomplish cross domain request , usage scenario ? why not jsonp ? 3 * @author yiminghe@gmail.com 4 */ 5 KISSY.add("ajax/XdrFlashTransport", function (S, io, DOM) { 6 7 var // current running request instances 8 maps = {}, 9 ID = "io_swf", 10 // flash transporter 11 flash, 12 doc = S.Env.host.document, 13 // whether create the flash transporter 14 init = false; 15 16 // create the flash transporter 17 function _swf(uri, _, uid) { 18 if (init) { 19 return; 20 } 21 init = true; 22 var o = '<object id="' + ID + 23 '" type="application/x-shockwave-flash" data="' + 24 uri + '" width="0" height="0">' + 25 '<param name="movie" value="' + 26 uri + '" />' + 27 '<param name="FlashVars" value="yid=' + 28 _ + '&uid=' + 29 uid + 30 '&host=KISSY.require(\'ajax\')" />' + 31 '<param name="allowScriptAccess" value="always" />' + 32 '</object>', 33 c = doc.createElement('div'); 34 DOM.prepend(c, doc.body || doc.documentElement); 35 c.innerHTML = o; 36 } 37 38 function XdrFlashTransport(xhrObj) { 39 S.log("use flash xdr"); 40 this.xhrObj = xhrObj; 41 } 42 43 S.augment(XdrFlashTransport, { 44 // rewrite send to support flash xdr 45 send:function () { 46 var self = this, 47 xhrObj = self.xhrObj, 48 c = xhrObj.config; 49 var xdr = c['xdr'] || {}; 50 // 不提供则使用 cdn 默认的 flash 51 _swf(xdr.src || (S.Config.base + "ajax/io.swf"), 1, 1); 52 // 简便起见,用轮训 53 if (!flash) { 54 // S.log("detect xdr flash"); 55 setTimeout(function () { 56 self.send(); 57 }, 200); 58 return; 59 } 60 self._uid = S.guid(); 61 maps[self._uid] = self; 62 63 // ie67 send 出错? 64 flash.send(c.url, { 65 id:self._uid, 66 uid:self._uid, 67 method:c.type, 68 data:c.hasContent && c.data || {} 69 }); 70 }, 71 72 abort:function () { 73 flash.abort(this._uid); 74 }, 75 76 _xdrResponse:function (e, o) { 77 S.log(e); 78 var self = this, 79 ret, 80 xhrObj = self.xhrObj; 81 82 // need decodeURI to get real value from flash returned value 83 xhrObj.responseText = decodeURI(o.c.responseText); 84 85 switch (e) { 86 case 'success': 87 ret = { status:200, statusText:"success" }; 88 delete maps[o.id]; 89 break; 90 case 'abort': 91 delete maps[o.id]; 92 break; 93 case 'timeout': 94 case 'transport error': 95 case 'failure': 96 delete maps[o.id]; 97 ret = { status:500, statusText:e }; 98 break; 99 } 100 if (ret) { 101 xhrObj._xhrReady(ret.status, ret.statusText); 102 } 103 } 104 }); 105 106 /*called by flash*/ 107 io['applyTo'] = function (_, cmd, args) { 108 // S.log(cmd + " execute"); 109 var cmds = cmd.split(".").slice(1), 110 func = io; 111 S.each(cmds, function (c) { 112 func = func[c]; 113 }); 114 func.apply(null, args); 115 }; 116 117 // when flash is loaded 118 io['xdrReady'] = function () { 119 flash = doc.getElementById(ID); 120 }; 121 122 /** 123 * when response is returned from server 124 * @param e response status 125 * @param o internal data 126 * @param c internal data 127 */ 128 io['xdrResponse'] = function (e, o, c) { 129 var xhr = maps[o.uid]; 130 xhr && xhr._xdrResponse(e, o, c); 131 }; 132 133 return XdrFlashTransport; 134 135 }, { 136 requires:["./base", 'dom'] 137 });