ajax的核心是通過XmlHttpRequest獲取非本頁內(nèi)容,而jsonp的核心則是動態(tài)添加
然后php方就會執(zhí)行backfunc(傳遞參數(shù));
所以流程就會分二步:
1:針對jsonp的預(yù)處理,主要是轉(zhuǎn)化拼接這些參數(shù),然后處理緩存,因為jsonp的方式也是靠加載script所以要關(guān)閉瀏覽器緩存
inspectPrefiltersOrTransports中,當(dāng)作了jsonp的預(yù)處理后,還要在執(zhí)行inspect(dataTypeOrTransport);的遞歸,就是為了關(guān)閉這個緩存機制
var dataTypeOrTransport = prefilterOrFactory(options, originalOptions, jqXHR); /** * 針對jonsp處理 */ if (typeof dataTypeOrTransport === "string" && !seekingTransport && !inspected[dataTypeOrTransport]) { //增加cache設(shè)置標(biāo)記 //不需要緩存 //dataTypes: Array[2] // 0: "script" // 1: "json" options.dataTypes.unshift(dataTypeOrTransport); inspect(dataTypeOrTransport); return false; } else if (seekingTransport) { return !(selected = dataTypeOrTransport); }
具體的預(yù)處理的代碼
// Detect, normalize options and install callbacks for jsonp requests// 向前置過濾器對象中添加特定類型的過濾器// 添加的過濾器將格式化參數(shù),并且為jsonp請求增加callbacksjQuery.ajaxPrefilter("json jsonp", function(s, originalSettings, jqXHR) { var callbackName, overwritten, responseContainer, // 如果是表單提交,則需要檢查數(shù)據(jù) jsonProp = s.jsonp !== false && (rjsonp.test(s.url) ? "url" : typeof s.data === "string" && !(s.contentType || "").indexOf("application/x-www-form-urlencoded") && rjsonp.test(s.data) && "data" ); // Handle iff the expected data type is "jsonp" or we have a parameter to set // 這個方法只處理jsonp,如果json的url或data有jsonp的特征,會被當(dāng)成jsonp處理 if (jsonProp || s.dataTypes[0] === "jsonp") { // Get callback name, remembering preexisting value associated with it // s.jsonpCallback時函數(shù),則執(zhí)行函數(shù)用返回值做為回調(diào)函數(shù)名 callbackName = s.jsonpCallback = jQuery.isFunction(s.jsonpCallback) ? s.jsonpCallback() : s.jsonpCallback; // Insert callback into url or form data // 插入回調(diào)url或表單數(shù)據(jù) // "test.php?symbol=IBM&callback=jQuery20309245402452070266_1402451299022" if (jsonProp) { s[jsonProp] = s[jsonProp].replace(rjsonp, "$1" + callbackName); } else if (s.jsonp !== false) { s.url += (ajax_rquery.test(s.url) ? "&" : "?") + s.jsonp + "=" + callbackName; } // Use data converter to retrieve json after script execution s.converters["script json"] = function() { if (!responseContainer) { jQuery.error(callbackName + " was not called"); } return responseContainer[0]; }; // force json dataType // 強制跟換類型 s.dataTypes[0] = "json"; // Install callback // 增加一個全局的臨時函數(shù) overwritten = window[callbackName]; window[callbackName] = function() { responseContainer = arguments; }; // Clean-up function (fires after converters) // 在代碼執(zhí)行完畢后清理這個全部函數(shù) jqXHR.always(function() { // Restore preexisting value window[callbackName] = overwritten; // Save back as free if (s[callbackName]) { // make sure that re-using the options doesn't screw things around s.jsonpCallback = originalSettings.jsonpCallback; // save the callback name for future use oldCallbacks.push(callbackName); } // Call if it was a function and we have a response if (responseContainer && jQuery.isFunction(overwritten)) { overwritten(responseContainer[0]); } responseContainer = overwritten = undefined; }); // Delegate to script return "script"; }});
jquery會在window對象中加載一個全局的函數(shù),當(dāng)代碼插入時函數(shù)執(zhí)行,執(zhí)行完畢后就會被移除。同時jquery還對非跨域的請求進行了優(yōu)化,如果這個請求是在同一個域名下那么他就會像正常的Ajax請求一樣工作。
分發(fā)器執(zhí)行代碼:
當(dāng)我們所有的參數(shù)都轉(zhuǎn)化好了,此時會經(jīng)過請求發(fā)送器用來處理發(fā)送的具體
為什么會叫做分發(fā)器,因為發(fā)送的請求目標(biāo)
ajax因為參雜了jsonp的處理,所以實際上的請求不是通過 xhr.send(XmlHttpRequest)發(fā)送的
而是通過get方式的腳本加載的
所以
transports對象在初始化構(gòu)件的時候,會生成2個處理器
所以
transport = inspectPrefiltersOrTransports(transports, s, options, jqXHR);
那么得到的transport就會根據(jù)當(dāng)前的處理的類型,來選擇采用哪種發(fā)送器(*、script)
針對script的請求器
聯(lián)系客服