Javascript 基于SWF的xhr和JS-Status 200但执行错误函数
我有一个SWF对象的实现来修改XHR对象,以满足IE的跨域请求 一旦对象可用,我将修改XHR,如下所示:Javascript 基于SWF的xhr和JS-Status 200但执行错误函数,javascript,flash,cross-domain,haxe,amplifyjs,Javascript,Flash,Cross Domain,Haxe,Amplifyjs,我有一个SWF对象的实现来修改XHR对象,以满足IE的跨域请求 一旦对象可用,我将修改XHR,如下所示: if ($.browser.msie) { amplify.subscribe("request.before.ajax", function (resource, settings, ajaxSettings, xhr) { if (resource.url.indexOf(requestConfig.apiUrl) != -1) { 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抛出的错误是:SyntaxError:无效字符
- 该错误是由反斜杠引起的:
“Username”:“DOM\\PRO4”
,它在某种程度上变成了浏览器的“DOM\PRO4”
,并给出了语法错误。但是服务器正在逃逸,因为我可以看到从服务器发送的原始数据已经\n但是由于某种原因,我可以理解flash可能正在破坏它
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;
}
}
//
导入flash.external.ExternalInterface;
导入flash.Lib;
导入haxe.Http;
导入flash.events.Event;
导入flash.external.ExternalInterface;
导入flash.display.Sprite;
类swfhtprequest{
公共静态变量版本:字符串='0.3';
公共静态var传输:Map=newmap();
公共静态函数中止(实例:Int){
transports.get(实例+“”).abort();
}
公共静态函数open(实例:Int,方法:String,url:String){
set(实例+“”,新传输(实例,方法,url));
}
公共静态函数send(实例:Int,数据:String){
transports.get(实例+“”).send(数据);
}
公共静态函数setRequestHeader(实例:Int,头:String,值:String){
transports.get(实例+“”).setRequestHeader(头,值);
}
公共静态函数版本(){
返回版本;
}
已加载私有静态函数(事件:事件):Void
{
flash.external.ExternalInterface.call(“swfHttpLoaded”);
}
公共静态函数main(){
flash.system.Security.allowDomain(“*”);
addCallback(“中止”,中止);
addCallback(“打开”,打开);
addCallback(“发送”,发送);
addCallback(“setRequestHeader”,setRequestHeader);
addCallback(“swfhtprequestversion”,version);
调用([“(函数(){”),
“如果(window.swfhtprequest)返回;”,
“var Class=函数(属性){”,
“var klass=function(){返回this.abort.apply(this);};”,
“klass.prototype=properties;”,
“klass.constructor=arguments.callee;”,
“返回克拉斯;”,
"};",
“window.swfhtprequest=新类({”,
“中止:函数(){”,
“如果(typeof this.instance!='未定义'){”,
“window.swfhtprequest.instances[this.instance]=null;”,
“window.swfhtprequest.engine.abort(this.instance);”,
"}",
“this.readyState=0;”,
“this.responseText=”;“,
“this.responseXML=null;”,
“this.status=0;”,
“this.statusText=”;“,
“this.instance=window.swfhtprequest.instances.length;”,
“window.swfhtprequest.instances.push(this);”,
"},",
“getAllResponseHeaders:function(){return null;},”,
“getResponseHeader:function(){return null;},”,
onreadystatechange:null,
“打开:函数(方法、url、异步、用户、密码){”,
“this.status=0;”,
“this.readyState=1;”,
“this.statusText=this.responseText=”;“,
“this.responseXML=null;”,
“window.swfhtprequest.engine.open(this.instance,method,url);”,
"},",
“发送:函数(数据){”,
//TODO:一旦haxe.Http为flash9目标支持setPostData(),此函数
//应该更新以允许文档作为数据。如果是这样,
//在发送给Flash executor之前,应该将其序列化为XML。
“window.swfhtprequest.engine.send(this.instance,data);”,
"},",
“setRequestHeader:函数(头,值){”,
“如果(this.readyState!=1 | | |!header | |!value)返回;”,
“window.swfhtprequest.engine.setRequestHeader(this.instance,header,value);”,
"}",
"});",
“window.swfhtprequest.instances=[];”,
“window.swfhtprequest.version='”+ver+“;”,
“var f=函数(标记){”,
“var elems=document.getElementsByTagName(标记);”,
“对于(var i=0;i您不再需要使用Flash进行跨域XHR,即使在IE中也是如此。根据您的图像判断,已启用
所有主要浏览器和IE 10+都具有跨域请求的本机支持。早期版本的IE支持检查访问控制允许源站
标题(部分CORS支持)
因此,除非您确实需要支持IE7或更低版本,否则请在公共函数onData(数据:字符串)
中使用常规XMLHttpRequest
和XDomainRequest
将其修改为以下内容后,现在一切正常:
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);
}
我必须支持ie7:(不清楚你在这里问什么。与其发布一大堆信息,不如尝试将其分解为非常小的部分,这些部分是有效的还是无效的。