Side navigation
#159 closed enhancement (fixed)
Opened August 30, 2006 09:32AM UTC
Closed September 26, 2006 02:39AM UTC
Last modified March 15, 2012 01:35AM UTC
Ajax refactoring
| Reported by: | will@willjessup | Owned by: | |
|---|---|---|---|
| Priority: | major | Milestone: | |
| Component: | ajax | Version: | |
| Keywords: | ajax | Cc: | |
| Blocked by: | Blocking: |
Description
Description
refactored the code in the ajax module so that things are homogenous in usage internally with the benefit of less lines of code, and more flexibility in creating and evaluating ajax requests
Changes & notes (non exhaustive)
ln 1514: $.fn.load needs to be looked at , i removed its funky one-off callback in favor of the global methods - but doing so should probably break its ability to execute on every matched item(untested)
$.ajax is now called w/ a single object both internally and externally jQuery.ajax({type: type, url: url, data: params, complete: callback, ifModified: ifModified});
$.httpData executes in only one place for each type of function
$.param executes in only one place, ever.
$.param returns if data = null
Added ability to pass ifModified anywhere in ajax object.
Tested
Firefox1.5 vs.
get (w/ and w/out data)
getifmodified (w/ and w/out data)
load (w/ and w/out data)
loadifmodified yada yada
and $.ajax
Example usage
$.ajax({
url: "/ajaxmessages.php",
type: "GET",
ifModified: 1,
error: function() { alert("error") },
success: function(json, status) {},
complete: function(json, status) {
eval("var args = " + json);
$("#ajaxUpdate").append('<div>' + args.messages[0] + '</div>');
}
});
CODE
/**
* Load HTML from a remote file and inject it into the DOM
*/
jQuery.fn.loadIfModified = function( url, params, callback ) {
this.load( url, params, callback, 1 );
};
jQuery.fn.load = function( url, params, callback, ifModified ) {
if ( url.constructor == Function )
return this.bind("load", url);
// Default to a GET request
var type = "GET";
// If the second parameter was provided
if ( params ) {
// If it's a function
if ( params.constructor == Function ) {
// We assume that it's the callback
callback = params;
params = null;
} else
type = "POST";
}
jQuery.ajax({type: type, url: url, data: params, complete: callback, ifModified: ifModified});
};
// If IE is used, create a wrapper for the XMLHttpRequest object
if ( jQuery.browser.msie && XMLHttpRequest == undefined )
XMLHttpRequest = function(){
return new ActiveXObject(
navigator.userAgent.indexOf("MSIE 5") >= 0 ?
"Microsoft.XMLHTTP" : "Msxml2.XMLHTTP"
);
};
// Attach a bunch of functions for handling common AJAX events
new function(){
var e = "ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess".split(',');
for ( var i = 0; i < e.length; i++ ) new function(){
var o = e[i];
jQuery.fn[o] = function(f){
return this.bind(o, f);
};
};
};
jQuery.extend({
/**
* Load a remote page using a GET request
*/
get: function( url, data, callback, type, ifModified ) {
if ( data.constructor == Function ) {
type = callback;
callback = data;
data = null;
}
// Build and start the HTTP Request
jQuery.ajax({type: "GET", url: url, data: data, complete: callback, ifModified: ifModified});
},
getIfModified: function( url, data, callback, type ) {
jQuery.get(url, data, callback, type, 1);
},
getScript: function( url, data, callback ) {
jQuery.get(url, data, callback, "script");
},
/**
* Load a remote page using a POST request.
*/
post: function( url, data, callback, type ) {
// Build and start the HTTP Request
jQuery.ajax({type: "POST", url: url, data: data, complete: callback});
},
// timeout (ms)
timeout: 0,
ajaxTimeout: function(timeout) {
jQuery.timeout = timeout;
},
// Last-Modified header cache for next request
lastModified: {},
/**
* A common wrapper for making XMLHttpRequests
*/
ajax: function(o) {
//Grab vars from object passed to $.ajax
ret = o.complete;
var ifModified = o.ifModified;
var success = o.success;
var error = o.error;
data = jQuery.param(o.data);
url = o.url;
type = o.type;
// Watch for a new set of requests
if ( ! jQuery.active++ )
jQuery.event.trigger( "ajaxStart" );
var requestDone = false;
// Create the request object
var xml = new XMLHttpRequest();
// Open the socket
xml.open(type || "GET", url, true);
// Set the correct header, if data is being sent
if ( data )
xml.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
// Set the If-Modified-Since header, if ifModified mode.
if ( ifModified )
xml.setRequestHeader("If-Modified-Since",
jQuery.lastModified[url] || "Thu, 01 Jan 1970 00:00:00 GMT" );
// Set header so calling script knows that it's an XMLHttpRequest
xml.setRequestHeader("X-Requested-With", "XMLHttpRequest");
// Make sure the browser sends the right content length
if ( xml.overrideMimeType )
xml.setRequestHeader("Connection", "close");
// Wait for a response to come back
var onreadystatechange = function(istimeout){
// The transfer is complete and the data is available, or the request timed out
if ( xml && (xml.readyState == 4 || istimeout == "timeout") ) {
requestDone = true;
var status = jQuery.httpSuccess( xml ) && istimeout != "timeout" ?
ifModified && jQuery.httpNotModified( xml, url ) ? "notmodified" : "success" : "error";
// Make sure that the request was successful or notmodified
if ( status != "error" ) {
// Cache Last-Modified header, if ifModified mode.
var modRes = xml.getResponseHeader("Last-Modified");
if ( ifModified && modRes ) jQuery.lastModified[url] = modRes;
// If a local callback was specified, fire it
if ( success ) success( jQuery.httpData(xml), status );
// Fire the global callback
jQuery.event.trigger( "ajaxSuccess" );
// Otherwise, the request was not successful
} else {
// If a local callback was specified, fire it
if ( error ) error( jQuery.httpData(xml), status );
// Fire the global callback
jQuery.event.trigger( "ajaxError" );
}
// The request was completed
jQuery.event.trigger( "ajaxComplete" );
// Handle the global AJAX counter
if ( ! --jQuery.active )
jQuery.event.trigger( "ajaxStop" );
// Process result
if ( ret ) ret( jQuery.httpData(xml), status);
// Stop memory leaks
xml.onreadystatechange = function(){};
xml = null;
}
};
xml.onreadystatechange = onreadystatechange;
// Timeout checker
if(jQuery.timeout > 0)
setTimeout(function(){
// Check to see if the request is still happening
if (xml) {
// Cancel the request
xml.abort();
if ( !requestDone ) onreadystatechange( "timeout" );
// Clear from memory
xml = null;
}
}, jQuery.timeout);
// Send the data
xml.send(data);
},
// Counter for holding the number of active queries
active: 0,
// Determines if an XMLHttpRequest was successful or not
httpSuccess: function(r) {
try {
return !r.status && location.protocol == "file:" ||
( r.status >= 200 && r.status < 300 ) || r.status == 304 ||
jQuery.browser.safari && r.status == undefined;
} catch(e){}
return false;
},
// Determines if an XMLHttpRequest returns NotModified
httpNotModified: function(xml, url) {
try {
var xmlRes = xml.getResponseHeader("Last-Modified");
// Firefox always returns 200. check Last-Modified date
return xml.status == 304 || xmlRes == jQuery.lastModified[url] ||
jQuery.browser.safari && xml.status == undefined;
} catch(e){}
return false;
},
// Get the data out of an XMLHttpRequest.
// Return parsed XML if content-type header is "xml" and type is "xml" or omitted,
// otherwise return plain text.
httpData: function(r,type) {
var ct = r.getResponseHeader("content-type");
var data = !type && ct && ct.indexOf("xml") >= 0;
data = type == "xml" || data ? r.responseXML : r.responseText;
// If the type is "script", eval it
if ( type == "script" ) eval.call( window, data );
return data;
},
// Serialize an array of form elements or a set of
// key/values into a query string
param: function(a) {
var s = [];
if(!a) return;
// If an array was passed in, assume that it is an array
// of form elements
if ( a.constructor == Array ) {
// Serialize the form elements
for ( var i = 0; i < a.length; i++ )
s.push( a[i].name + "=" + encodeURIComponent( a[i].value ) );
// Otherwise, assume that it's an object of key/value pairs
} else {
// Serialize the key/values
for ( var j in a )
s.push( j + "=" + encodeURIComponent( a[j] ) );
}
// Return the resulting serialization
return s.join("&");
}
});
Attachments (0)
Change History (4)
Changed September 06, 2006 05:50AM UTC by comment:1
| priority: | major → trivial |
|---|---|
| resolution: | → wontfix |
| status: | new → closed |
Changed September 14, 2006 01:55AM UTC by comment:2
| keywords: | ajax, pwn → ajax |
|---|---|
| summary: | Ajax p-p-p-powerup → Ajax refactoring |
not sure why this was closed?
Changed September 23, 2006 08:39AM UTC by comment:3
| milestone: | 1.0 |
|---|---|
| priority: | trivial → major |
| resolution: | wontfix |
| status: | closed → reopened |
| version: | 1.0b1 |
Changed September 26, 2006 02:39AM UTC by comment:4
| resolution: | → fixed |
|---|---|
| status: | reopened → closed |
Most of this has already been added in - thanks for the code, Will.
hu hu your text is great!
But so great that it doesn't stay in his box ;) (safari 2.0.4 - 419.3)