$.ajax({ url:"http://www.microsoft.com", //設置請求的url dataType:"json", //設置數據返回格式爲json async:true,//設置請求是否異步,默認爲異步。 data:{"id":"value"}, //設置發送的數據 type:"GET", //設置請求方式 beforeSend:function(){ //設置請求前的回調 }, success:function(req){ //設置請求成功後的回調 }, complete:function(){ //設置請求完成後的回調 }, error:function(){ //設置請求出錯處理的回調 } });
從ajax標準的請求調用代碼中咱們看到傳入了一個參數,這個參數是一個對象。對象中定義了XMLHttpRequest對象所需的數據集合。javascript
咱們知道.ajax()是jQuery對XMLHttpRequest對象發送HTTP請求的一個js封裝接口,因此總歸要作一下幾部:建立XMLHttpRequest對象,而後open進行tcp連接,其次添加相關的頭部信息和定義回調函數等等設置,最後send給服務器並攜帶相關數據。java
xmlhttp = new XMLHttpRequest(); xmlhttp.onreadystatechange=callback; xmlhttp.open("POST","test.do",true); // // 設置POST請求的請求頭 xmlhttp.setRequestHeader("Content-Type" , "application/json"); xmlhttp.send('password=123&username=mingzi');
如圖所示,ajax定義在.extend()函數調用的惟一參數對象中,咱們前面解讀extend源碼的時候知道,若是extend函數中只有一個參數(對象)的時候,這個參數就是源對象,jQuery爲目標對象。這樣等效於在jQuery對象上擴展這個源對象的全部屬性,其中之一的ajax就被擴展到jQuery對象上,成爲jQuery靜態工具函數的其中一員。ajax
1)構造完整的請求選項集,並修正選項。【預處理AJAX全部數據合併用戶定義的數據和默認數據】
2)構造jqXHR對象,並增長異步隊列的行爲。【http頭部數據】
3)構造回調函數done(status,nativeStatusText,responses,headers),響應完成以後被調用,負責轉換數據類型、執行回調函數、觸發全局事件。【回調函數模型,處理全部狀態的回調】
4)應用前置過濾器,繼續修正選項。【數據處理】
5)獲取請求發送器,並調用方法send(requestHeaders,done)發送請求。【建立XMLHttpRequest對象及open、send及回調處理等方法】
6)最後返回jqXHR對象。json
1)傳進來的參數對象預處理數組
A. 若是第一個參數是對象類型,那option 就直接等於 第一個參數 url。而後消滅url = undefined。瀏覽器
B. 經過與一個空對象()進行或運算,強制option爲一個對象!服務器
ajax: function( url, options ) { // If url is an object, simulate pre-1.5 signature if ( typeof url === "object" ) { options = url; url = undefined; } // Force options to be an object options = options || {}; s = jQuery.ajaxSetup( {}, options ), }
2) 建立最終選項對象(XMLHttpRequest所需的數據集):將傳進來的對象與默認選項對象進行深度合併。網絡
A. jQuery.ajaxSetup — ajaxExtend() —— jQuery.ajaxSettings——jQuery.ajaxSettings.flatOptionsapp
B. 簡而言之是經過以上的幾個函數調用將默認選項對象jQuery.ajaxSettings和用戶自定義的ajax參數(選項對象)經過ajaxExtend進行深度合併(除了url和context不深度外),獲得一個最終的選項對象s。以下:cors
jqXHR對象是瀏覽器原生XMLHttpRequest對象的超集,當請求發送器不是XMLHttpRequest時,jqXHR對象會盡量地模擬XMLHttpRequest的功能。而且,jqXHR對象還具有異步隊列的方法和行爲。爲了兼容XMLHttpRequest,jqXHR對象暴露了如下屬性和方法:
❑readyState:表示當前jqXHR對象的狀態。
❑status:響應的HTTP狀態碼。
❑statusText:響應的HTTP狀態描述。
❑responseText、responseXML:響應的文本內容、XML文檔。
❑setRequestHeader(name,value):設置請求頭 […]❑getAllResponseHeaders():獲取響應頭字符串。
❑getResponseHeader(key):獲取指定名稱的響應頭的值。
❑overrideMimeType(type):用於覆蓋MIME類型。
❑abort(statusText):取消本次請求。
1)在.ajax()函數中根據須要直接調用done;
2)傳入發送器的send()函數當send的回調函數對發送數據完成後回調執行。
transport.send( requestHeaders, done ); //傳入整個done回調函數放到transport.send(參數中 send: function( headers, complete ) { //定義發送器send中的回調函數Callback callback = function( type ) { return function() { if ( callback ) { if ( type === "abort" ) { xhr.abort(); } else if ( type === "error" ) { complete( 0, "error" ); } else { complete( xhrSuccessStatus[ xhr.status ] || xhr.status, xhr.statusText, ( xhr.responseType || "text" ) !== "text" || typeof xhr.responseText !== "string" ? { binary: xhr.response } : { text: xhr.responseText }, xhr.getAllResponseHeaders() // Listen to events //啓動回調函數的監聽 xhr.onload = callback();
1)常規的:
s.url = ( ( url || s.url || location.href ) + "" ) .replace( rprotocol, location.protocol + "//" ); // Alias method option to type as per ticket #12004 s.type = options.method || options.type || s.method || s.type;
2)應用前置過濾器繼續修正選項對象
prefilters = {},//空過濾器 ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),//向對象prefilters中添加前置過濾器 inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );//從對象prefilters中找到數據類型對應的前置過濾器數組,逐個執行
1)咱們能夠從如下代碼中看到transports發送器中含有XMLHttpRequest對象,及open建立網絡連接、send()發送和abort()取消發送方法,還有執行回調函數complete 。
2)一次send的執行:transport.send( requestHeaders, done ); done是一個回調函數模型。能夠執行各類http狀態的回調!
transports = {}, ajaxTransport: addToPrefiltersOrTransports( transports ), //經過inspectPrefiltersOrTransports獲取發送器 transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR ); //發送器實體 jQuery.ajaxTransport( function( options ) { var callback, errorCallback; // Cross domain only allowed if supported through XMLHttpRequest if ( support.cors || xhrSupported && !options.crossDomain ) { return { send: function( headers, complete ) { //構造XMLHttpRequest對象放在發送器裏 var i,xhr = options.xhr(); xhr.open(options.type,options.url,options.async,options.username,options.password); // Set headers for ( i in headers ) { xhr.setRequestHeader( i, headers[ i ] ); } // Callback callback = function( type ) { return function() { if ( callback ) { callback = errorCallback = xhr.onload = xhr.onerror = xhr.onabort = xhr.onreadystatechange = null; if ( type === "abort" ) { xhr.abort(); } else if ( type === "error" ) { complete( xhr.status, xhr.statusText ); } } else { complete( xhrSuccessStatus[ xhr.status ] || xhr.status, xhr.statusText, ( xhr.responseType || "text" ) !== "text" || typeof xhr.responseText !== "string" ? { binary: xhr.response } : { text: xhr.responseText }, xhr.getAllResponseHeaders() ); } } }; }; xhr.onload = callback(); }, abort: function() { if ( callback ) { callback(); } } }; } } ); //構造XMLHttpRequest對象放在發送器裏 options.xhr() = jQuery.ajaxSettings.xhr = function() { try { return new window.XMLHttpRequest(); } catch ( e ) {} };