mirror of
https://github.com/ACSPRI/queXS
synced 2024-04-02 12:12:16 +00:00
270 lines
6.7 KiB
JavaScript
270 lines
6.7 KiB
JavaScript
/**
|
|
* XMLHttpRequest Wrapper
|
|
* @category HTML
|
|
* @package AJAX
|
|
* @author Joshua Eichorn <josh@bluga.net>
|
|
* @copyright 2005 Joshua Eichorn
|
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
|
*/
|
|
function HTML_AJAX_HttpClient() { }
|
|
HTML_AJAX_HttpClient.prototype = {
|
|
// request object
|
|
request: null,
|
|
|
|
// timeout id
|
|
_timeoutId: null,
|
|
|
|
callbackComplete: true,
|
|
|
|
// has this request been aborted
|
|
aborted: false,
|
|
|
|
// method to initialize an xmlhttpclient
|
|
init:function()
|
|
{
|
|
try {
|
|
// Mozilla / Safari
|
|
//this.xmlhttp = new HTML_AJAX_IframeXHR(); //uncomment these two lines to test iframe
|
|
//return;
|
|
this.xmlhttp = new XMLHttpRequest();
|
|
} catch (e) {
|
|
// IE
|
|
var XMLHTTP_IDS = new Array(
|
|
'MSXML2.XMLHTTP.5.0',
|
|
'MSXML2.XMLHTTP.4.0',
|
|
'MSXML2.XMLHTTP.3.0',
|
|
'MSXML2.XMLHTTP',
|
|
'Microsoft.XMLHTTP' );
|
|
var success = false;
|
|
for (var i=0;i < XMLHTTP_IDS.length && !success; i++) {
|
|
try {
|
|
this.xmlhttp = new ActiveXObject(XMLHTTP_IDS[i]);
|
|
success = true;
|
|
} catch (e) {}
|
|
}
|
|
if (!success) {
|
|
try{
|
|
this.xmlhttp = new HTML_AJAX_IframeXHR();
|
|
this.request.iframe = true;
|
|
} catch(e) {
|
|
throw new Error('Unable to create XMLHttpRequest.');
|
|
}
|
|
}
|
|
}
|
|
},
|
|
|
|
// check if there is a call in progress
|
|
callInProgress: function()
|
|
{
|
|
switch ( this.xmlhttp.readyState ) {
|
|
case 1:
|
|
case 2:
|
|
case 3:
|
|
return true;
|
|
break;
|
|
default:
|
|
return false;
|
|
break;
|
|
}
|
|
},
|
|
|
|
// make the request defined in the request object
|
|
makeRequest: function()
|
|
{
|
|
if (!this.xmlhttp) {
|
|
this.init();
|
|
}
|
|
|
|
try {
|
|
if (this.request.Open) {
|
|
this.request.Open();
|
|
}
|
|
else if (HTML_AJAX.Open) {
|
|
HTML_AJAX.Open(this.request);
|
|
}
|
|
|
|
if (this.request.multipart) {
|
|
if (document.all) {
|
|
this.iframe = true;
|
|
} else {
|
|
this.xmlhttp.multipart = true;
|
|
}
|
|
}
|
|
|
|
// set onreadystatechange here since it will be reset after a completed call in Mozilla
|
|
var self = this;
|
|
this.xmlhttp.open(this.request.requestType,this.request.completeUrl(),this.request.isAsync);
|
|
if (this.request.customHeaders) {
|
|
for (i in this.request.customHeaders) {
|
|
this.xmlhttp.setRequestHeader(i, this.request.customHeaders[i]);
|
|
}
|
|
}
|
|
if (this.request.customHeaders && !this.request.customHeaders['Content-Type']) {
|
|
var content = this.request.getContentType();
|
|
//opera is stupid for anything but plain text or xml!!
|
|
if(window.opera && content != 'application/xml')
|
|
{
|
|
this.xmlhttp.setRequestHeader('Content-Type','text/plain; charset=utf-8');
|
|
this.xmlhttp.setRequestHeader('x-Content-Type', content + '; charset=utf-8');
|
|
}
|
|
else
|
|
{
|
|
this.xmlhttp.setRequestHeader('Content-Type', content + '; charset=utf-8');
|
|
}
|
|
}
|
|
|
|
if (this.request.isAsync) {
|
|
if (this.request.callback) {
|
|
this.callbackComplete = false;
|
|
}
|
|
this.xmlhttp.onreadystatechange = function() { self._readyStateChangeCallback(); }
|
|
} else {
|
|
this.xmlhttp.onreadystatechange = function() {}
|
|
}
|
|
var payload = this.request.getSerializedPayload();
|
|
if (payload) {
|
|
this.xmlhttp.setRequestHeader('Content-Length', payload.length);
|
|
}
|
|
this.xmlhttp.send(payload);
|
|
|
|
if (!this.request.isAsync) {
|
|
if ( this.xmlhttp.status == 200 ) {
|
|
HTML_AJAX.requestComplete(this.request);
|
|
if (this.request.Load) {
|
|
this.request.Load();
|
|
} else if (HTML_AJAX.Load) {
|
|
HTML_AJAX.Load(this.request);
|
|
}
|
|
|
|
return this._decodeResponse();
|
|
} else {
|
|
var e = new Error('['+this.xmlhttp.status +'] '+this.xmlhttp.statusText);
|
|
e.headers = this.xmlhttp.getAllResponseHeaders();
|
|
this._handleError(e);
|
|
}
|
|
}
|
|
else {
|
|
// setup timeout
|
|
var self = this;
|
|
this._timeoutId = window.setTimeout(function() { self.abort(true); },this.request.timeout);
|
|
}
|
|
} catch (e) {
|
|
this._handleError(e);
|
|
}
|
|
},
|
|
|
|
// abort an inprogress request
|
|
abort: function (automatic)
|
|
{
|
|
if (this.callInProgress()) {
|
|
this.aborted = true;
|
|
this.xmlhttp.abort();
|
|
|
|
if (automatic) {
|
|
HTML_AJAX.requestComplete(this.request);
|
|
this._handleError(new Error('Request Timed Out: time out was '+this.request.timeout+'ms'));
|
|
}
|
|
}
|
|
},
|
|
|
|
// internal method used to handle ready state changes
|
|
_readyStateChangeCallback:function()
|
|
{
|
|
try {
|
|
switch(this.xmlhttp.readyState) {
|
|
// XMLHTTPRequest.open() has just been called
|
|
case 1:
|
|
break;
|
|
// XMLHTTPRequest.send() has just been called
|
|
case 2:
|
|
if (this.request.Send) {
|
|
this.request.Send();
|
|
} else if (HTML_AJAX.Send) {
|
|
HTML_AJAX.Send(this.request);
|
|
}
|
|
break;
|
|
// Fetching response from server in progress
|
|
case 3:
|
|
if (this.request.Progress) {
|
|
this.request.Progress();
|
|
} else if (HTML_AJAX.Progress ) {
|
|
HTML_AJAX.Progress(this.request);
|
|
}
|
|
break;
|
|
// Download complete
|
|
case 4:
|
|
window.clearTimeout(this._timeoutId);
|
|
if (this.aborted) {
|
|
if (this.request.Load) {
|
|
this.request.Load();
|
|
} else if (HTML_AJAX.Load) {
|
|
HTML_AJAX.Load(this.request);
|
|
}
|
|
}
|
|
else if (this.xmlhttp.status == 200) {
|
|
if (this.request.Load) {
|
|
this.request.Load();
|
|
} else if (HTML_AJAX.Load ) {
|
|
HTML_AJAX.Load(this.request);
|
|
}
|
|
|
|
var response = this._decodeResponse();
|
|
|
|
if (this.request.callback) {
|
|
this.request.callback(response);
|
|
this.callbackComplete = true;
|
|
}
|
|
}
|
|
else {
|
|
var e = new Error('HTTP Error Making Request: ['+this.xmlhttp.status+'] '+this.xmlhttp.statusText);
|
|
this._handleError(e);
|
|
}
|
|
HTML_AJAX.requestComplete(this.request);
|
|
break;
|
|
}
|
|
} catch (e) {
|
|
this._handleError(e);
|
|
}
|
|
},
|
|
|
|
// decode response as needed
|
|
_decodeResponse: function() {
|
|
//try for x-Content-Type first
|
|
var content = null;
|
|
try {
|
|
content = this.xmlhttp.getResponseHeader('X-Content-Type');
|
|
} catch(e) {}
|
|
if(!content || content == null)
|
|
{
|
|
content = this.xmlhttp.getResponseHeader('Content-Type');
|
|
}
|
|
//strip anything after ;
|
|
if(content.indexOf(';') != -1)
|
|
{
|
|
content = content.substring(0, content.indexOf(';'));
|
|
}
|
|
// hook for xml, it doesn't need to be unserialized
|
|
if(content == 'application/xml')
|
|
{
|
|
return this.xmlhttp.responseXML;
|
|
}
|
|
var unserializer = HTML_AJAX.serializerForEncoding(content);
|
|
//alert(this.xmlhttp.getAllResponseHeaders()); // some sort of debug hook is needed here
|
|
return unserializer.unserialize(this.xmlhttp.responseText);
|
|
},
|
|
|
|
// handle sending an error where it needs to go
|
|
_handleError: function(e)
|
|
{
|
|
HTML_AJAX.requestComplete(this.request,e);
|
|
if (this.request.onError) {
|
|
this.request.onError(e);
|
|
} else if (HTML_AJAX.onError) {
|
|
HTML_AJAX.onError(e,this.request);
|
|
}
|
|
else {
|
|
throw e;
|
|
}
|
|
}
|
|
}
|