.

Sunday, February 26, 2006

A simple, leak free, defensive XMLHttpRequest Wrapper #

As you may have known Internet Explorer is the king of the leakers.

And XMLHttpRequest (in other words "Microsoft.XMLHTTP" ActiveX component) is not an exception to this.

In this post, I will try to explain where the component may leak and how we can avoid those leaks.

Let us begin with a typical wrapper:

[LISTING 1]
var _this=XHRequest.prototype;
function XHRequest(){
this.init();
}

_this.init=function(){
var sourceElement=this;
this._xhr=this.getObject();
if(!this._xhr)return;
this._xhr.onreadystatechange=function(){
var obj=sourceElement.getObject();
if(obj.readyState==4){
/*
* 404: file not found.
* 200: OK.
* 304: reading from cache.
*/
if(obj.status==200 OR obj.status==304)
sourceElement.oncomplete(obj.responseText,obj.responseXML);
else
sourceElement.onerror(obj.status,obj.statusText);
}
};
};


where getObject may be defined as:

[LISTING 2]
_this.getObject=function(){
if(this._xhr)return this._xhr;
else if(window.XMLHttpRequest)return new XMLHttpRequest();
else if(window.ActiveXObject)
return new ActiveXObject("Microsoft.XMLHTTP");
else return null;
};


The problem is that, we have created a closure in Listing 1:



and closures between DOM world and JS world will cause a memory leak in IE.

To sort out this we will need to implement a few helpers:

First let us alter the onreadystatechange handler a bit:
... code snippped ...
/*
* 404: file not found.
* 200: OK
* 304: reading from cache.
*/
if(obj.status==200obj.status==304)
sourceElement.oncomplete(obj.responseText,obj.responseXML);
else sourceElement.onerror(obj.status,obj.statusText);
/*to prevent IE memory leak due to circular COM referencing.*/
sourceElement._cleanup();


And the _cleanup method as:

_this._cleanup=function(){
if(!this._xhr)return;

/*
* this._xhr.onreadystatechange = null generates
* a "type mismatch" error in IE.
* So, to release circular reference
* we delete this._xhr.onreadystatechange;
*
* Actually, either setting this._xhr=null
* or "delete"ing this._xhr.onreadystatechange
* is enough to prevent memory leak.
*
* That is, the first line of the code below
* is just added to be on the safe side.
*/
delete this._xhr.onreadystatechange;
this._xhr=null;
};


And, for the interested, here follows the entire lightweight
XMLHttp wrapper (which I am currently enhancing a lot and will fully integrate to the next version of sardalya. )

Sorry for the indentation and typos in the code. It is blogger's WYSIWYG mode's fault not mine :)

_this=XHRequest.prototype;
function XHRequest()
{
this.init();
}

_this.init=function()
{
var sourceElement=null;

this._xhr=this.getObject();
if(!this._xhr)return;

sourceElement=this;

this._xhr.onreadystatechange=function()
{
var obj=sourceElement.getObject();
if(obj.readyState==4)
{
if(obj.status==200 OR
obj.status==304)sourceElement.oncomplete(
obj.responseText,obj.responseXML);
else sourceElement.onerror(obj.status,obj.statusText);
sourceElement._cleanup();
}
};
};


_this.getObject=function()
{
if(this._xhr)return this._xhr;
else if(window.XMLHttpRequest)return new XMLHttpRequest();
else if(window.ActiveXObject)return new ActiveXObject("Microsoft.XMLHTTP");
else return null;
};

_this.finalize=function()
{
if(!this._xhr)return;
this._cleanup();
};

_this.get=function(strURL,_blnSync)
{
if(!this._xhr)return null;
if(!_blnSync)_blnSync=false;

this._xhr.open("GET",strURL,!_blnSync);
this._xhr.send(null);
};

_this.getSynchronized=function(strURL)
{
this.get(strURL,true);
};

_this.abort=function()
{
if(this._xhr)this._xhr.abort();
this._cleanup();
};

_this._cleanup=function()
{
if(!this._xhr)return;
delete this._xhr.onreadystatechange;
this._xhr=null;
};

_this.oncomplete=function(strResponseText,objResponseXML)
{
alert("Completed everything.");
};

_this.onerror=function(intStatus,strStatusText)
{
alert("An error occured but my owner is too lazy to handle it.");
};

 bu yaziyi sevdin mi?  hemen una ekle!
 


0 Coments


Post a Comment

Links to this post:


Create a Link

<< Home




Recent Posts

RSS

RSS register icon

Other Blogs

Various

Sponsor

Profile Information

Browser I Suggest

Sponsor

Dikkatimi Çekenler