然后php方就会执行backfunc(传递参数);
所以流程就会分二步:
1:针对jsonp的预处理,主要是转化拼接这些参数,然后处理缓存,因为jsonp的方式也是靠加载script所以要关闭浏览器缓存
inspectPrefiltersOrTransports中,当作了jsonp的预处理后,还要在执行inspect(dataTypeOrTransport);的递归,就是为了关闭这个缓存机制
var dataTypeOrTransport = prefilterOrFactory(options, originalOptions, jqXHR);
/**
* 针对jonsp处理*/
if (typeof dataTypeOrTransport === "string" && !seekingTransport && !inspected[dataTypeOrTransport]) {
//增加cache设置标记
//不需要缓存
//dataTypes: Array[2]
//0: "script"
//1: "json"
options.dataTypes.unshift(dataTypeOrTransport);
inspect(dataTypeOrTransport);
return false;
} else if (seekingTransport) {
return !(selected = dataTypeOrTransport);
}
具体的预处理的代码
//Detect, normalize options and install callbacks for jsonp requests//向前置过滤器对象中添加特定类型的过滤器//添加的过滤器将格式化参数,并且为jsonp请求增加callbacks
jQuery.ajaxPrefilter("json jsonp", function(s, originalSettings, jqXHR) {
var callbackName,
overwritten,
responseContainer,
//如果是表单提交,则需要检查数据
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的特征,会被当成jsonp处理
if (jsonProp || s.dataTypes[0] === "jsonp") {
//Get callback name, remembering preexisting value associated with it
//s.jsonpCallback时函数,则执行函数用返回值做为回调函数名
callbackName = s.jsonpCallback = jQuery.isFunction(s.jsonpCallback) ?
s.jsonpCallback() :
s.jsonpCallback;
//Insert callback into url or form data
//插入回调url或表单数据
//"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
//增加一个全局的临时函数
overwritten = window[callbackName];
window[callbackName] = function() {
responseContainer = arguments;
};
//Clean-up function (fires after converters)
//在代码执行完毕后清理这个全部函数
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对象中加载一个全局的函数,当代码插入时函数执行,执行完毕后就会被移除。同时jquery还对非跨域的请求进行了优化,如果这个请求是在同一个域名下那么他就会像正常的Ajax请求一样工作。
分发器执行代码:
当我们所有的参数都转化好了,此时会经过请求发送器用来处理发送的具体
为什么会叫做分发器,因为发送的请求目标
ajax因为参杂了jsonp的处理,所以实际上的请求不是通过 xhr.send(XmlHttpRequest)发送的
而是通过get方式的脚本加载的
所以
transports对象在初始化构件的时候,会生成2个处理器
*: Array[1] 针对xhr方式
script: Array[1] 针对script,jsonp方式
所以
transport = inspectPrefiltersOrTransports(transports, s, options, jqXHR);
那么得到的transport就会根据当前的处理的类型,来选择采用哪种发送器(*、script)
针对script的请求器
jQuery.ajaxTransport("script", function(s) {
//This transport only deals with cross domain requests
if (s.crossDomain) {
var script, callback;
return {
send: function(_, complete) {
script = jQuery("