dataType 類型的轉化
dataType 類型的參數,可以是 xml, json, script, or html 或者干脆為空,那么 jQuery 就需要一個方法去判斷當前是屬于什么數據處理,就此引入了 ajaxConvert 處理響應轉化器,解析出正確的 dataType 類。
response = ajaxConvert(s, response, jqXHR, isSuccess);
分析下 dataType 無法就那么幾種情況
1. dataType 為空,自動轉化
此時 jQuery 只能根據頭部信息來猜測當前需要處理的類型,刪除掉通配 dataType,得到返回的 Content-Type。
while (dataTypes[0] === "*") { dataTypes.shift(); if (ct === undefined) { ct = s.mimeType || jqXHR.getResponseHeader("Content-Type"); } }
通過 xhr.getAllResponseHeaders() 得到頭部信息,然后去匹配 Content-Type 所有對象的值即可,當然找到這個 Content-Type = “html”,我們還得看看有沒有對應處理的方法,如果有就需要替換這個 dataTypes。
看看是不是我們能處理的 Content-Type,比如圖片這類二進制類型就不好處理了。
if (ct) { // 實際上能處理的就是text、xml和json for (type in contents) { if (contents[type] && contents[type].test(ct)) { dataTypes.unshift(type); break; } } }
經過這個流程后,dataTypes 本來是 * 就變成了對應的 html了,這是 jquery 內部的自動轉化過。
2. dataType開發者指定
xml, json, script, html, jsop類型轉換器將服務端響應的 responseText 或 responseXML,轉換為請求時指定的數據類型 dataType,如果沒有指定類型就依據響應頭 Content-Type 自動處理。
類型轉換器的執行過程
response = ajaxConvert(s, response, jqXHR, isSuccess);
流程
1.遍歷dataTypes中對應的處理規則【"script","json"】 2.制作jqXHR對象的返回數據接口 json: "responseJSON" text: "responseText" xml: "responseXML" 如:jqXHR.responseText: "{"a":1,"b":2,"c":3,"d":4,"e":5}" 3.生成轉化器對應的匹配規則,尋找合適的處理器 4.返回處理后的數據response
分析一下特殊的 jsonp 的轉化流程,先看看轉化對應的處理器。
jsonp
converters["script json"] = function() { if (!responseContainer) { jQuery.error(callbackName + " was not called"); } return responseContainer[0]; };
jsonp 的轉化器只是很簡單的從 responseContainer 取出了對應的值,所以 responseContainer 肯定在轉化之后就應該把數據給轉化成數組對象了,當然做源碼分析需要一點自己猜想能力,比如 responseContainer 這個數組對象如何而來?
那么我們知道 jsonp 的處理的原理,還是通過加載 script,然后服務器返回一個回調函數,responseContainer 數據就是回調函數的實參,所以需要滿足 responseContainer 的處理,必須要先滿足腳本先加載,所以我們要去分發器中找對應的加載代碼,首先responseContainer 是內部變量,只有一個來源處,在預處理的時候增加一個全局的臨時函數,然后代碼肯定是執行了這個函數才能把 arguments 參數賦給 responseContainer。
overwritten = window[callbackName]; window[callbackName] = function() { responseContainer = arguments; }; //callbcakName是內部創建的一個尼瑪函數名 jQuery203029543792246840894_1403062512436 = function() { responseContainer = arguments; };
我們發送請求:
http://192.168.1.114/yii/demos/test.php?backfunc=jQuery203029543792246840894_1403062512436&action=aaron&_=1403062601515
服務器那邊就回調后,執行了 jQuery203029543792246840894_1403062512436(responseContainer ) 所以全局的 callbackName 函數需要在分發器中腳本加載后才能執行,從而才能截取到服務器返回的數據。
請驗證,完成請求
由于請求次數過多,請先驗證,完成再次請求
打開微信掃碼自動綁定
綁定后可得到
使用 Ctrl+D 可將課程添加到書簽
舉報