35ajax,jQuery源码分析系列(35) : Ajax

本文详细解析了jQuery中的jsonp预处理机制,涉及参数转化、缓存管理与跨域请求优化。通过了解如何在jQuery的ajaxPrefilter中实现jsonp回调处理,以及如何通过script请求器发送和管理数据,提升性能和兼容性。
摘要由CSDN通过智能技术生成

然后php方就会执行backfunc(传递参数);

所以流程就会分二步:

1:针对jsonp的预处理,主要是转化拼接这些参数,然后处理缓存,因为jsonp的方式也是靠加载script所以要关闭浏览器缓存

inspectPrefiltersOrTransports中,当作了jsonp的预处理后,还要在执行inspect(dataTypeOrTransport);的递归,就是为了关闭这个缓存机制

60916311_1.gif

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);

}

60916311_1.gif

具体的预处理的代码

60916311_1.gif

//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";

}

});

60916311_1.gif

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的请求器

60916311_1.gif

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("

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值