Jquery. ajax source code

Source: Internet
Author: User

The role of the framework is to simplify what we do, but it is flexible. Jquery is the mainstay of the js framework. It is flexible and powerful.
 
Jquery encapsulates ajax perfectly, not to mention its powerful underlying ajax functions, but its upper-layer get, post, getscript, and getJson functions are quite handy for various applications. Why do we need to look at the source code? One is idle, and the other is to find the problem in case of a problem. Third .......
There is an object ajaxSeetings in jquery. The most basic configuration of ajax requests is here. The structure is as follows:
AjaxSettings: {url: location. href, global: true, type: "GET", contentType: "application/x-www-form-urlencoded", processData: true, async: true,/* timeout: 0, data: null, username: null, password: null, traditional: false, * // Create the request object; microsoft failed to properly // implement the XMLHttpRequest in IE7 (can't request local files), // so we use the ActiveXObject when it is avail Able // This function can be overriden by calling jQuery. ajaxSetup xhr: window. XMLHttpRequest & (window. location. protocol! = "File:" |! Window. ActiveXObject )? Function () {return new window. XMLHttpRequest () ;}: function () {try {return new window. activeXObject ("Microsoft. XMLHTTP ") ;}catch (e) {}}, accepts: {xml:" application/xml, text/xml ", html:" text/html ", script: "text/javascript, application/javascript", json: "application/json, text/javascript", text: "text/plain", _ default :"*/*"}}
Basically, the name represents its configuration project, and processData may be unfamiliar. When we use get and other upper-layer functions to request resources, we pass a key/value object. For example, $. get ("xxxx", {name: 'pr', password: 'pr '},......); If process is set to true, {name: 'pr', password: 'pr'} is converted to name = pr & password = pr; in this way, if ajax is set to get, the updated string is appended to the url. If it is set to false, this conversion is not performed. The default value is true, and it is recommended that you do not change the value. It is worth noting that the content is of course the property xhr, which is a function. Of course, the function will eventually return the browser-compatible XmlHttpRequest object. The core operation object of ajax is it, which frees us from the tangle of compatibility issues when constructing the XmlHttpRequest object.
Ajax: function (origSettings). ajax accepts a configuration object, which is structured like the preceding ajaxSettings,
Var s = jQuery. extend (true, {}, jQuery. ajaxSettings, origSettings); var jsonp, status, data, callbackContext = origSettings & origSettings. context | s, type = s. type. toUpperCase (); // convert data if not already a string if (s. data & s. processData & typeof s. data! = "String") {s. data = jQuery. param (s. data, s. traditional );}
First, the function merges the default configuration with the configuration passed in. Note that {} exists in the function. This will not affect the original values of ajaxSettings and originSettings. CallbackContext is the context of the function that executes the ajax callback function. Let's not talk about anything else. Then, based on data, ProcessData, and data, determine whether to convert the data object to a parameter string. Jquery. param is a tool function. traditional is used to determine whether to perform in-depth traversal to generate parameter strings. For more information, see the jquery documentation.
// Handle JSONP Parameter Callbacks if (s. dataType = "jsonp") {if (type = "GET") {if (! Jsre. test (s. url) {s. url + = (rquery. test (s. url )? "&":"? ") + (S. jsonp |" callback ") +" =? ";}} Else if (! S. data |! Jsre. test (s. data) {s. data = (s. data? S. data + "&": "") + (s. jsonp | "callback") + "=? ";} S. dataType = "json";} // Build temporary JSONP function if (s. dataType = "json" & (s. data & jsre. test (s. data) | jsre. test (s. url) {jsonp = s. jsonpCallback | ("jsonp" + jsc ++); // Replace the =? Sequence both in the query string and the data if (s. data) {s. data = (s. data + ""). replace (jsre, "=" + jsonp + "$1");} s. url = s. url. replace (jsre, "=" + jsonp + "$1"); // We need to make sure // that a JSONP style response is executed properly s. dataType = "script"; // Handle JSONP-style loading window [jsonp] = window [jsonp] | function (tmp) {data = tmp; success (); complete (); // Garbage collect window [jsonp] = undefined; try {delete window [jsonp];} catch (e) {}if (head) {head. removeChild (script );}};}
The next special request data type is jsonp. jsonp is actually an unofficial protocol, mainly cross-origin access. Later, you can see that it will be processed in a similar way as the request type is 'script.
If you are not familiar with jsonp, you can go to the Internet to find relevant information or skip jsonp without affecting subsequent reading.
Jsre is a regular expression jsre == \? (& | $)/, Which mainly matches '=? 'This is actually a unique string in the jsonp request. If there is no corresponding character in the url, add the string unique to the jsonp request. Requery is also a regular expression /\? /Is used to match the question mark. If the original url contains ?, If the url contains parameters, the connection character "&" is used; otherwise, the parameter "?" is used ?. If the configuration object contains jsonp, the callback function name of jsonp is specified. Otherwise, the default callback function name is used. If ajax requests adopt the post method, you only need to splice the data in the configuration object with a string. Datatype is set to json for further refinement. Whether in get or other methods, jsre will be used before processing. Only when the string does not contain the jsonp feature string '=? ).
Next, construct the jsonp callback function. As mentioned above, if the jsonp attribute is not specified, the default value is Callback. If jsonpCallback is specified, a unique callback function name will be constructed directly but not available. What can be used? Is there a good solution besides time? Jsc is the current time, jsc = now (); then use this callback function name to replace ?, In this way, the format of the parameter string is met.
Window [jsonp], which is used to register the callback function.
If (s. dataType = "script" & s. cache = null) {s. cache = false;} if (s. cache = false & type = "GET") {var ts = now (); // try replacing _ = if it is there var ret = s. url. replace (rts, "$1 _ =" + ts + "$2"); // if nothing was replaced, add timestamp to the end s. url = ret + (ret = s. url )? (Rquery. test (s. url )? "&":"? ") +" _ = "+ Ts:" ") ;}// If data is available, append data to url for get requests if (s. data & type = "GET") {s. url + = (rquery. test (s. url )? "&":"? ") + S. data;} // Watch for a new set of requests if (s. global &&! JQuery. active ++) {jQuery. event. trigger ("ajaxStart");} // Matches an absolute URL, and saves the domain var parts = rurl.exe c (s. url), remote = parts & (parts [1] & parts [1]! = Location. protocol | parts [2]! = Location. host); // If we're re requesting a remote document // and trying to load JSON or Script with a GET if (s. dataType = "script" & type = "GET" & remote) {var head = document. getElementsByTagName ("head") [0] | document.doc umentElement; var script = document. createElement ("script"); script. src = s. url; if (s. scriptCharset) {script. charset = s. scriptCharset;} // Handle Script loadin G if (! Jsonp) {var done = false; // Attach handlers for all browsers script. onload = script. onreadystatechange = function () {if (! Done &&(! This. readyState | this. readyState = "loaded" | this. readyState = "complete") {done = true; success (); complete (); // Handle memory leak in IE script. onload = script. onreadystatechange = null; if (head & script. parentNode) {head. removeChild (script) ;}};}// Use insertBefore instead of appendChild to circumvent an IE6 bug. // This arises when a base node is used (#2709 and #4378 ). head. insertBefore (script, head. firstChild); // We handle everything using the script element injection return undefined ;}
For ajax requests, there may be cached files (of course, only when the request method is Get, please refer to w3school for the specific differences between Get and post in ajax requests ), when the request format is 'script' (may be later converted, such as jsonp), there is no cached file. The implementation method is to add a timestamp for each request, and ts is now, same as jsc.
If the request method is Get, add the request parameters to the url.
The following describes the ajax Custom Event list, which is an official ajax event list. (You can see the corresponding translation at the end of this page. Limited Water products)
AjaxStart (Global Event)
This event is broadcast if an Ajax request is started and no other Ajax requests are currently running.
(This event is triggered only when an ajax request has started and no other ajax requests are running)
BeforeSend (Local Event)
This event, which is triggered before an Ajax request is started, allows you to modify the XMLHttpRequest object (setting additional headers, if need be .)
(This event is triggered before an ajax request starts. Allows you to modify the request object (such as setting other headers ))
AjaxSend (Global Event)
This global event is also triggered before the request is run.
(This event is triggered before the request is run)
Success (Local Event)
This event is only called if the request was successful (no errors from the server, no errors with the data ).
(This event is triggered only when the put request is successful (no errors are returned from the server and no errors are returned ))
AjaxSuccess (Global Event)
This event is also only called if the request was successful.
(This event is triggered when the request is successful)
Error (Local Event)
This event is only called if an error occurred with the request (you can never have both an error and a success callback with a request ).
Triggered when a request error occurs (one request cannot trigger both the error and success callback functions at the same time)
AjaxError (Global Event)
This global event behaves the same as the local error event.
Same as above
Complete (Local Event)
This event is called regardless of if the request was successful, or not. You will always receive a complete callback, even for synchronous requests.
The request is triggered no matter whether the request is successful or not.
AjaxComplete (Global Event)
This event behaves the same as the complete event and will be triggered every time an Ajax request finishes.
Same as above
AjaxStop (Global Event)
This global event is triggered if there are no more Ajax requests being processed.
Currently, no request processing is triggered.
The trigger conditions for these events are listed above. When these conditions are met, trigger these events. As for whether to register a processing function, this is the user's business.
With reference to the above trigger conditions, you can understand the trigger of these events in ajax functions. The initial value of jquery. active is 0;
Rurl =/^ (\ w + :)? \/([^ \/? #] +)/Mainly obtains the rest name and Host Name of the url. If the protocol name or Host Name of the current request is different from the content of the current object in the browser, remote cross-origin access is enabled. Set remote to true.
If the request is a remote resource with Get and the request type is script, the dom object of the script is created, related attributes are set, and the script has been loaded. Finally, set the callback function when the script is loaded successfully.
The final returned undefine is the final step for processing script loading. If the script is loaded, the request ends here.
Here, we mainly process two data types of requests: script and jsonp.
Var requestDone = false; // Create the request object var xhr = s. xhr (); if (! Xhr) {return;} // Open the socket // Passing null username, generates a login popup on Opera (#2865) if (s. username) {xhr. open (type, s. url, s. async, s. username, s. password);} else {xhr. open (type, s. url, s. async);} // Need an extra try/catch for cross domain requests in Firefox 3 try {// Set the correct header, if data is being sent if (s. data | origSettings & origSettings. contentType) {Xhr. setRequestHeader ("Content-Type", s. contentType);} // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. if (s. ifModified) {if (jQuery. lastModified [s. url]) {xhr. setRequestHeader ("If-Modified-Since", jQuery. lastModified [s. url]);} if (jQuery. etag [s. url]) {xhr. setRequestHeader ("If-None-Match", jQuery. etag [s. url]) ;}// Set header so the called script know S that it's an XMLHttpRequest // Only send the header if it's not a remote XHR if (! Remote) {xhr. setRequestHeader ("X-Requested-With", "XMLHttpRequest");} // Set the Accepts header for the server, depending on the dataType xhr. setRequestHeader ("Accept", s. dataType & s. accepts [s. dataType]? S. accepts [s. dataType] + ", */*": s. accepts. _ default);} catch (e) {}// Allow custom headers/mimetypes and early abort if (s. beforeSend & s. beforeSend. call (callbackContext, xhr, s) === false) {// Handle the global AJAX counter if (s. global &&! -- JQuery. active) {jQuery. event. trigger ("ajaxStop");} // close opended socket xhr. abort (); return false;} if (s. global) {trigger ("ajaxSend", [xhr, s]);}
This code mainly obtains xhr, sets some headers before xhrsend, and calls some callback functions, such as beforeSend. CallBackcontext is the execution context of the callback function we set in originSettings. From the judgment condition, we can see that if we return false in beforesennd, this request will be canceled. If no other request exists, the ajaxstop event is triggered.
Var onreadystatechange = xhr. onreadystatechange = function (isTimeout) {// The request was aborted if (! Xhr | xhr. readyState = 0 | isTimeout = "abort") {// Opera doesn't call onreadystatechange before this point // so we simulate the call if (! RequestDone) {complete ();} requestDone = true; if (xhr) {xhr. onreadystatechange = jQuery. noop;} // The transfer is complete and the data is available, or the request timed out} else if (! RequestDone & xhr & (xhr. readyState = 4 | isTimeout = "timeout") {requestDone = true; xhr. onreadystatechange = jQuery. noop; status = isTimeout = "timeout "? "Timeout ":! JQuery. httpSuccess (xhr )? "Error": s. ifModified & jQuery. httpNotModified (xhr, s. url )? "Notmodified": "success"; var errMsg; if (status = "success") {// Watch for, and catch, XML document parse errors try {// process the data (runs the xml through httpData regardless of callback) data = jQuery. httpData (xhr, s. dataType, s);} catch (err) {status = "parsererror"; errMsg = err ;}} // Make sure that the request was successful or notmodified if (status = "success" | status === "Notmodified") {// JSONP handles its own success callback if (! Jsonp) {success () ;}} else {jQuery. handleError (s, xhr, status, errMsg);} // Fire the complete handlers complete (); if (isTimeout = "timeout") {xhr. abort ();} // Stop memory leaks if (s. async) {xhr = null ;}}};
I think onreadystatechange is another important part of ajax functions.
The most important thing is when status = 'success. The following describes the specific content of the jquery tool function httpData.
HttpData: function (xhr, type, s) {var ct = xhr. getResponseHeader ("content-type") | "", xml = type = "xml" |! Type & ct. indexOf ("xml") & gt; = 0, data = xml? Xhr. responseXML: xhr. responseText; if (xml & data.doc umentElement. nodeName = "parsererror") {jQuery. error ("parsererror");} // Allow a pre-filtering function to sanitize the response // s is checked to keep backwards compatibility if (s & s. dataFilter) {data = s. dataFilter (data, type);} // The filter can actually parse the response if (typeof data = "string") {// Get the JavaS Jsonobject, if JSON is used. if (type = "json" |! Type & ct. indexOf ("json") & gt; = 0) {data = jQuery. parseJSON (data); // If the type is "script", eval it in global context} else if (type = "script" |! Type & ct. indexOf ("javascript") & gt; = 0) {jQuery. globalEval (data) ;}} return data ;},
The content returned by ajax is in two formats: responseText and responseXML. If datafilter is set, this function filters data before all data operations. In our request format, json, jsonp, and script all recall string returned data. For jsonp or script, execute the js Code corresponding to data and then return data. (That is, client script injection). If it is of the json type, the string is first parsed as a js object and then returned.
// Override the abort handler, if we can (IE doesn't allow it, but that's OK) // Opera doesn' t fire onreadystatechange at all on abort try {var oldAbort = xhr. abort; xhr. abort = function () {if (xhr) {oldAbort. call (xhr) ;}onreadystatechange ("abort") ;};} catch (e) {}// Timeout checker if (s. async & s. timeout & gt; 0) {setTimeout (function () {// Check to see if the request is still Pening if (xhr &&! RequestDone) {onreadystatechange ("timeout") ;}}, s. timeout);} // Send the data try {xhr. send (type = "POST" | type = "PUT" | type = "DELETE "? S. data: null);} catch (e) {jQuery. handleError (s, xhr, null, e); // Fire the complete handlers complete ();} // firefox 1.5 doesn't fire statechange for sync requests if (! S. async) {onreadystatechange ();} function success () {// If a local callback was specified, fire it and pass it the data if (s. success) {s. success. call (callbackContext, data, status, xhr);} // Fire the global callback if (s. global) {trigger ("ajaxSuccess", [xhr, s]) ;}} function complete () {// Process result if (s. complete) {s. complete. call (callbackContext, xhr, status);} // Request was completed if (s. global) {trigger ("ajaxComplete", [xhr, s]);} // Handle the global AJAX counter if (s. global &&! -- JQuery. active) {jQuery. event. trigger ("ajaxStop") ;}} function trigger (type, args) {(s. context? JQuery (s. context): jQuery. event). trigger (type, args);} // return XMLHttpRequest to allow aborting the request etc. return xhr;
Below are some details about processing, event triggering, browser compatibility processing, and of course xhr. send (type = "POST" | type = "PUT" | type = "DELETE "? S. data: null );
The function returns the xhr request object. In addition, the success conplete function seems to be a callback function written by us to replace the default function. In fact, there are also ajax tasks in success and compete, therefore, the callback function we write in settings is called by the corresponding ajax function.
Finally, we have registered a callback function for the jsonp request. You may ask when to call this function, in fact, it depends on whether the script returned from the server has called this function. Because we have passed the callback function name to the server. (This is my understanding, and I know little about jsonp)
Although the original ajax request results only have two types of responseText and responseXML, ajax makes a lot of processing for US based on the specific Protocol. Although we do not see it, we should still understand it.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.