Jquery 实现原理之 Ajax
一:Jquery Ajax底層接口有:$.ajaxPrefilters、$.ajaxTransport、$.ajaxSettings、$ajaxSetup、$ajaxSettings;
其中$.ajaxPrefilters 和 $.ajaxTransport是通過inspectPrefiltersOrTransports構造器來創建的;
$.ajaxPrefilters:是一個前置過濾器,在每個請求被$.ajaxTransport()和$.ajax()處理之前調用,設置自定義ajax選項或者修改現有的選項,簡單說就是hack的 做法,但是比事件處理的hack的手法更加高明。可以用來處理參數,注冊回調等。
例如:改變代理服務器的域請求
1 $.ajaxPrefilter("+*", function( options ) { 2 if ( options.crossDomain ) { 3 options.url = "http://mydomain.net/proxy/" + encodeURIComponent( options.url ); 4 options.crossDomain = false; 5 } 6 });?
$.ajaxTransport:是一個請求分發器,是發送請求的具體實現,比如xhr就用xmlhttprequest來實現,script就是通過head中插入script標簽來實現.
例如:用來攔截發送的請求
1 $.ajaxTransport("+*", function(options, originalOptions, jqXHR) { 2 return { 3 send: function(headers, completeCallback) { 4 var status = 404; 5 var statusText = "error"; 6 var response = { 7 text: "" 8 }; 9 var item = { 10 url: "/paapi/v1/datapoints/pa", 11 data: data.groupsdatapoint 12 }; 13 if (!item) { 14 console.log("require mock data: \n" + originalOptions.url); 15 } else { 16 status = 200; 17 statusText = "ok"; 18 var data = item.data; 19 response.text = data; 20 } 21 setTimeout(function() { 22 completeCallback(status, statusText, response); 23 }, 0); 24 } 25 }; 26 });二: ajax的實現
實現ajax的目的是什么?
實現ajax的目的主要是對不同的dataType的具體處理和實現,比如'jsonp'應該怎么處理,'script'怎么處理,'*'怎么處理;
對此ajax模塊的做法是,提供一個基本的模塊ajax,然后通過插件形式來實現對不同dataType的處理。
ajax暴露ajaxPrefilter: addToPrefiltersOrTransports( prefilters ) ,?ajaxTransport: addToPrefiltersOrTransports( transports )是給插件用的,可以注冊自己的dataType處理函數。
其中prefilters={'jsonp': function() {}, '*': function(){}, 'script':function(){}}可能是這樣的,ajax在每個請求發送之前,根據dataType調用prefilters中的函數進行預處理,然后調用transport中的對應函數來發送請求。
addToPrefiltersOrTransports()方法如下:
1 function addToPrefiltersOrTransports(structure) { 2 3 // dataTypeExpression is optional and defaults to "*" 4 return function(dataTypeExpression, func) { 5 6 if (typeof dataTypeExpression !== "string") { 7 func = dataTypeExpression; 8 dataTypeExpression = "*"; 9 } 10 11 var dataType, 12 i = 0, 13 dataTypes = dataTypeExpression.toLowerCase().match(rnotwhite) || []; 14 15 if (jQuery.isFunction(func)) { 16 // For each dataType in the dataTypeExpression 17 while ((dataType = dataTypes[i++])) { 18 // Prepend if requested 19 if (dataType[0] === "+") { 20 dataType = dataType.slice(1) || "*"; 21 (structure[dataType] = structure[dataType] || []).unshift(func); 22 23 // Otherwise append 24 } else { 25 (structure[dataType] = structure[dataType] || []).push(func); 26 } 27 } 28 } 29 }; 30 }該函數功能就是把某一個dataType對應的處理函數func存進structure中,實際就是一個簡單的注冊事件。
1 // Base inspection function for prefilters and transports 2 function inspectPrefiltersOrTransports(structure, options, originalOptions, jqXHR) { 3 4 var inspected = {}, 5 seekingTransport = (structure === transports); 6 7 function inspect(dataType) { 8 var selected; 9 inspected[dataType] = true; 10 jQuery.each(structure[dataType] || [], function(_, prefilterOrFactory) { 11 var dataTypeOrTransport = prefilterOrFactory(options, originalOptions, jqXHR); 12 if (typeof dataTypeOrTransport === "string" && !seekingTransport && !inspected[dataTypeOrTransport]) { 13 options.dataTypes.unshift(dataTypeOrTransport); 14 inspect(dataTypeOrTransport); 15 return false; 16 } else if (seekingTransport) { 17 return !(selected = dataTypeOrTransport); 18 } 19 }); 20 return selected; 21 } 22 23 return inspect(options.dataTypes[0]) || !inspected["*"] && inspect("*"); 24 } 25 }該代碼時取調用dataType對應的prefilters和transports函數而已。
?
Ajax完成一部請求的全過程:
- 創建了一個jqXHR對象,這個對象就是ajax的返回值
- 用deferred對象封裝jqXHR對象,因此可以實現鏈式的異步操作:xhr.complete(x).success(x).errorl(x),這里的complete,success和error就是promise對象的add, done和fail的別名而已。
- 調用函數inspectPrefiltersOrTransports( prefilters, s, options, jqXHR ),那些插件注冊的prefilters函數就在這里被調用了。
- 做了一大對后續的處理,比如設置header參數,設置緩存cache
- 調用inspectPrefiltersOrTransports( transports, s, options, jqXHR )函數發送請求
- 定義了done函數,當請求發送結束之后做后續處理,包括調用convert轉換結果、設置statusText,調用deferred.resolveWith觸發異步回調等
- 最后返回了jqXHR對象
?
轉載于:https://www.cnblogs.com/thonrt/p/5395718.html
總結
以上是生活随笔為你收集整理的Jquery 实现原理之 Ajax的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 一款完整的多用户微信公众平台开发源码,带
- 下一篇: ELK实践(三)北京历年空气质量数据分析