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)