2013-07-18 34 views
0

我有SWF對象的實現來修改IE的跨域請求的XHR對象。基於SWF的xhr和amplifyJS - 狀態200但錯誤函數得到執行

一旦對象可我修改療法XHR這樣的:

if ($.browser.msie) { 
    amplify.subscribe("request.before.ajax", function (resource, settings, ajaxSettings, xhr) { 
     if (resource.url.indexOf(requestConfig.apiUrl) != -1) { 
      xhr.setRequestHeader("Accept", "application/xml, text/xml"); 
      var shr = new SWFHttpRequest();     
      ajaxSettings.xhr = function() { 
       return shr; 
      }; 
      ajaxSettings.crossDomain = false; 
      ajaxSettings.error = function (e) { 
       // Returns the data object I expect: 
       alert(e.responseText); 
      } 
     } 
    }); 
}; 

我的jQuery ajaxError拋出的錯誤是:語法錯誤:無效字符

  • 錯誤是由一個反斜槓引起的:

當我在我的JSON中,例如:"Username" : "DOM\\PRO4"它以某種方式變成"DOM\PRO4"給瀏覽器,並給予Syn稅收錯誤。但服務器正在逃跑,因爲我可以看到從服務器發送的原始數據具有\但由於某種原因,我可以理解Flash可能會破壞這一點。

enter image description here

enter image description here

響應從IE身體是:

{ 
"ResponseCode": 200, 
"ResponseDescription": "OK", 
"ResponseEntity": [ 
    { 
     "Id": "6d0d9471-f118-4984-9182-a20300a037b6", 
     "Name": "DYN", 
     "ConnectionTypeId": "20000000-0000-0000-0003-000000000003", 
     "ConnectionTypeName": null, 
     "Address": "http://54.229.51.444:7777/CRMServer", 
     "UserName": "DOM\\PRO4", 
     "Password": "", 
     "AddedById": "20000000-0000-0000-0004-000000000001", 
     "DateAdded": "07/22/2013 09:43:20", 
     "DateModified": "22/07/2013 15:00:01", 
     "ModifiedById": "", 
     "TypeName": "Dynamics" 
    } 
] 
} 

,你可以看到用戶名是正確轉義,但THR AJAX設置錯誤警報顯示了responseText的用戶名只有1反斜槓。

,如果你還需要看看SWF對象,其改進的一個開源模塊的版本使用haXe的開發:

import flash.external.ExternalInterface; 
import flash.Lib; 
import haxe.Http; 
import flash.events.Event; 
import flash.external.ExternalInterface; 
import flash.display.Sprite; 

class SWFHttpRequest { 

    public static var ver:String = '0.3'; 

    public static var transports:Map<String,Transport> = new Map(); 

    public static function abort(instance:Int) { 
     transports.get(instance + '').abort(); 
    } 

    public static function open(instance:Int, method:String, url:String) { 
     transports.set(instance + '', new Transport(instance, method, url)); 
    } 

    public static function send(instance:Int, data:String) { 
     transports.get(instance + '').send(data); 
    } 

    public static function setRequestHeader(instance:Int, header:String, value:String) { 
     transports.get(instance + '').setRequestHeader(header, value); 
    } 

    public static function version() { 
     return ver; 
    } 

    private static function onLoaded(event:Event):Void 
    { 
     flash.external.ExternalInterface.call("swfHttpLoaded"); 
    } 

    public static function main() { 
     flash.system.Security.allowDomain("*");  
     ExternalInterface.addCallback("abort",abort); 
     ExternalInterface.addCallback("open",open); 
     ExternalInterface.addCallback("send",send); 
     ExternalInterface.addCallback("setRequestHeader",setRequestHeader); 
     ExternalInterface.addCallback("SWFHttpRequestVersion",version); 
     ExternalInterface.call([ "(function(){", 
      "if (window.SWFHttpRequest) return;", 
      "var Class = function(properties){", 
       "var klass = function(){ return this.abort.apply(this); };", 
       "klass.prototype = properties;", 
       "klass.constructor = arguments.callee;", 
       "return klass;", 
      "};", 
      "window.SWFHttpRequest = new Class({", 
       "abort: function(){", 
        "if (typeof this.instance != 'undefined') {", 
         "window.SWFHttpRequest.instances[this.instance] = null;", 
         "window.SWFHttpRequest.engine.abort(this.instance);", 
        "}", 
        "this.readyState = 0;", 
        "this.responseText = '';", 
        "this.responseXML = null;", 
        "this.status = 0;", 
        "this.statusText = '';", 
        "this.instance = window.SWFHttpRequest.instances.length;", 
        "window.SWFHttpRequest.instances.push(this);", 
       "},", 
       "getAllResponseHeaders: function(){ return null; },", 
       "getResponseHeader: function(){ return null; },", 
       "onreadystatechange: null,", 
       "open: function(method, url, async, user, password){", 
        "this.status = 0;", 
        "this.readyState = 1;", 
        "this.statusText = this.responseText = '';", 
        "this.responseXML = null;", 
        "window.SWFHttpRequest.engine.open(this.instance, method, url);", 
       "},", 
       "send: function(data){", 
        // TODO: Once haxe.Http supports setPostData() for flash9 targets, this function 
        // should be updated to allow for a Document as the data. When that's the case, 
        // it should be serialized as XML prior to sending over to the Flash executor. 
        "window.SWFHttpRequest.engine.send(this.instance, data);", 
       "},", 
       "setRequestHeader: function(header, value){", 
        "if (this.readyState != 1 || !header || !value) return;", 
        "window.SWFHttpRequest.engine.setRequestHeader(this.instance, header, value);", 
       "}", 
      "});", 
      "window.SWFHttpRequest.instances = [];", 
      "window.SWFHttpRequest.version = '" + ver + "';", 
      "var f = function(tag){", 
       "var elems = document.getElementsByTagName(tag);", 
       "for (var i=0; i<elems.length; i++) if (elems[i].SWFHttpRequestVersion) return elems[i];", 
      "};", 
      "window.SWFHttpRequest.engine = f('embed') || f('object');", 
     "})" ].join('')); 
     var params = Lib.current.loaderInfo.parameters; 
     if (Reflect.hasField(params,'onload')) ExternalInterface.call(Reflect.field(params,'onload')); 
     Lib.current.loaderInfo.addEventListener(Event.COMPLETE, onLoaded); 
    } 
} 

class Transport { 

    var active:Bool; 
    var instance:Int; 
    var method:String; 
    var url:String; 
    var http:Http; 

    public function new(instance:Int, method:String, url:String) { 
     this.active = true; 
     this.instance = instance; 
     this.method = method.toUpperCase(); 
     this.url = url; 
     this.http = new Http(this.url); 
     this.http.onData = this.onData; 
     this.http.onError = this.onError; 
     this.http.onStatus = this.onStatus;  
    } 

    public function send(?data:String) { 
     if (data==null) return this.http.request(this.method=='POST'); 
     // NOTE: Once haxe.Http supports the setPostData() method for flash9 targets, 
     // all the following should be replaced by: this.http.setPostData(data); 
     // var re = ~/^(.*?)=(.*)$/; 
     // var pairs:Array<String> = data.split('&'); 
     // var ud = function(s){ 
      // try { return StringTools.urlDecode(s); } 
      // catch (e:Dynamic) { } 
      // return s; 
     // }; 
     // for(i in 0...pairs.length) { 
      // if (re.match(pairs[i])) this.http.setParameter(ud(re.matched(1)), ud(re.matched(2))); 
      // else this.http.setParameter(ud(pairs[i]), ''); 
     // } 
     this.http.setPostData(data); 
     return this.http.request(this.method=='POST'); 
    } 

    public function setRequestHeader(header:String, value:String) { 
     this.http.setHeader(header, value); 
    } 

    public function onData(data:String) { 
     if (!this.active) return; 
     ExternalInterface.call([ "(function(instance, data){", 
      "var shr = window.SWFHttpRequest.instances[instance];", 
      "if (!shr) return;", 
      "shr.status = 200;", 
      "shr.statusText = 'OK';", 
      "shr.readyState = 4;", 
      "shr.responseText = data;", 
      "try {", 
       "if (window.DOMParser) {", 
        "var dp = new DOMParser();", 
        "shr.responseXML = dp.parseFromString(data, 'text/xml');", 
       "} else {", 
        "shr.responseXML = new ActiveXObject('Microsoft.XMLDOM');", 
        "shr.responseXML.async = 'false';", 
        "shr.responseXML.loadXML(data);", 
       "}", 
      "} catch(error) { shr.responseXML = null; }", 
      "if (shr.onreadystatechange && typeof shr.onreadystatechange=='function') shr.onreadystatechange();", 
     "})" ].join(''), this.instance, data); 
    } 

    public function onError(msg:String) { 
     if (!this.active) return; 
     ExternalInterface.call([ "(function(instance){", 
      "var shr = window.SWFHttpRequest.instances[instance];", 
      "if (!shr) return;", 
      "shr.status = 404;", 
      "shr.statusText = 'Not Found';", 
      "shr.readyState = 4;", 
      "shr.responseText = null;", 
      "shr.responseXML = null;", 
      "if (shr.onreadystatechange && typeof shr.onreadystatechange=='function') shr.onreadystatechange();", 
     "})" ].join(''), this.instance); 
    } 

    public function onStatus(status:Int) { 
     if (!this.active || status==200) return; 
     ExternalInterface.call([ "(function(instance, status){", 
      "var shr = window.SWFHttpRequest.instances[instance];", 
      "if (!shr) return;", 
      "shr.status = status;", 
      "if (shr.onreadystatechange && typeof shr.onreadystatechange=='function') shr.onreadystatechange();", 
     "})" ].join(''), this.instance, status); 
    } 

    public function abort() { 
     this.active = false; 
    } 

} 

// 
+0

目前還不清楚你問這裏。不要發佈大量的信息,而是嘗試將其分解成非常小的部分,這些部分可能不工作。 – jimbojw

回答

0

in public function onData(data:String)數據沒有正確的轉義。

修改此之後是現在下面的東西如預期:

public function onData(data:String) { 
    if (!this.active) return; 
    var stringified = haxe.Json.stringify(haxe.Json.parse(data)); 
    var stringifiedEscaped = StringTools.replace(stringified, "\\", "\\\\"); 
    ExternalInterface.call([ "(function(instance, data){", 
     "var shr = window.SWFHttpRequest.instances[instance];", 
     "if (!shr) return;", 
     "shr.status = 200;", 
     "shr.statusText = 'OK';", 
     "shr.readyState = 4;", 
     "shr.responseText = data;", 
     "try {", 
      "if (window.DOMParser) {", 
       "var dp = new DOMParser();", 
       "shr.responseXML = dp.parseFromString(data, 'text/xml');", 
      "} else {", 
       "shr.responseXML = new ActiveXObject('Microsoft.XMLDOM');", 
       "shr.responseXML.async = 'false';", 
       "shr.responseXML.loadXML(data);", 
      "}", 
     "} catch(error) { shr.responseXML = null; }", 
     "if (shr.onreadystatechange && typeof shr.onreadystatechange=='function') shr.onreadystatechange();", 
    "})" ].join(''), this.instance, stringifiedEscaped); 
} 
+0

有人請更正確地回答這個問題,並就這個問題提供一些信息,以便更多的信息被暴露,我也可以給這100分 – XGreen

0

你不需要使用Flash跨域XHR了,即使在IE中。根據您的圖片判斷,CORS headers已啓用。

所有主流瀏覽器和IE 10+都支持跨域請求。以前版本的IE支持XDomainRequest object,它檢查Access-Control-Allow-Origin標題(部分CORS支持)。

所以,除非你確實需要支持IE 7或以下版本,否則請使用常規的XMLHttpRequestXDomainRequest

+0

我必須支持IE7 :( – XGreen

相關問題