Sunday, May 19, 2024
 Popular · Latest · Hot · Upcoming
47
rated 0 times [  51] [ 4]  / answers: 1 / hits: 53675  / 15 Years ago, mon, march 1, 2010, 12:00:00

I'm developing a simple auxiliary class to send requests using XmlHttpRequest (code below). But I cant make it work. At google chrome, for example, I get the error INVALID_STATE_ERR: DOM Exception 11 and at the other browsers I get a status == 0.



//@method XRequest: Object constructor. As this implements a singleton, the object can't be created calling the constructor, GetInstance should be called instead
function XRequest() {
this.XHR = XRequest.CreateXHR();
}
XRequest.instance = null;

//@method static GetInstance: Creates a singleton object of type XRequest. Should be called whenever an object of that type is required.
//@return: an instance of a XRequest object
XRequest.GetInstance = function() {
if(XRequest.instance == null) {
XRequest.instance = new XRequest();
}
return XRequest.instance;
}

//@method static CreateXHR: Implments a basic factory method for creating a XMLHttpRequest object
//@return: XMLHttp object or null
XRequest.CreateXHR = function() {
var xhr = null;
var factory = [
function() { return new XMLHttpRequest(); },
function() { return new ActiveXObject(Msxml2.XMLHTTP); },
function() { return new ActiveXObject(Microsoft.XMLHTTP); }
];

for(var i = 0; i < factory.length; ++i) {
var f = factory[i];
xhr = f();
if(xhr) return xhr;
}
return null;
}

XRequest.prototype.SetRequestHeader = function(name, value) {
if(this.XHR) {
this.XHR.setRequestHeader(name, value);
}
}

XRequest.prototype.SendRequest = function(args) {
var async = true;
var type = ;
var url = ;
var username = ;
var password = ;
var body = null;
var success = null;
var failure = null;

for(e in args) {
switch(e) {
case async:
async = args[e];
break;
case type:
type = args[e];
break;
case success:
success = args[e];
break;
case failure:
failure = args[e];
break;
case url:
url = args[e];
break;
case username:
username = args[e];
break;
case password:
password = args[e];
break;
case body:
body = args[e];
break;
case setHeader:
var h = args[e].split(:);
if(h.length == 2) {
this.SetRequestHeader(h[0], h[1]);
}
break;
}
}

var that = this;
this.XHR.onreadystatechange = function() {
alert(readyState == + that.XHR.readyState + status == + that.XHR.status);
if(that.XHR.readyState == 4) {
if(that.XHR.status == 200 || that.XHR.status == 0) {
if(success) success(that.XHR);
} else {
if(failure) failure();
}
}
};
this.XHR.open(type, url, async, username, password);
this.XHR.send(body);
}


Example of usage:



<script language=javascript>
function onLoad() {
var x = XRequest.GetInstance();
x.SendRequest({type:GET,
setHeader:Accept:text/html, image/png, image/*, */*,
url: http://your_server.com/getData?param1=test,
success:onSuccess, failure:onFail
});
}

function onSuccess(obj) {
alert(OK);
}

function onFail() {
alert(Not at this time!);
}
</script>

More From » ajax

 Answers
1

Regardless, you can simplify your SendRequest method by creating a mixin instead of using a giant switch.



XRequest.prototype.SendRequest = function(params) {
var defaultParams = {
async: true,
type: ,
url: ,
username: ,
password: ,
body: null,
success: null,
failure: null
};

for ( var i in defaultParams ) {
if ( defaultParams.hasOwnProperty(i) && typeof params[i] == undefined ) {
params[i] = defaultParams[i];
}
}

var that = this;
this.XHR.onreadystatechange = function() {
if ( that.XHR.readyState == 4 ) {
if ( that.XHR.status == 200 || that.XHR.status == 0 ) {
if ( params.success ) {
params.success(that.XHR);
}
} else {
if ( params.failure ) {
params.failure();
}
}
}
};

this.XHR.open(
params.type, parms.url, params.async, params.username, params.password
);

// It doesn't make sense to have a for/switch here when you're only handling
// one case
if ( params.setHeader ) {
var h = params.setHeader.split(:);
if ( h.length == 2) {
this.SetRequestHeader(h[0], h[1]);
}
}

this.XHR.send(params.body);
};


Also be careful: your existing for..in loops have two distinct problems:




  1. You're not using var and causing a global to be created: for (e in args) should be for (var e in args)

  2. Whenever you use for..in, you should always check to make sure that each key is a direct member of the object, and not something inherited inadvertently through prototype



.



for ( var i in obj ) {
if ( obj.hasOwnProperty(i) ) {
// do stuff here
}
}

[#97459] Thursday, February 25, 2010, 15 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
yesseniadajab

Total Points: 258
Total Questions: 101
Total Answers: 127

Location: Mexico
Member since Mon, Sep 12, 2022
2 Years ago
;