jQuery源码 Ajax模块分析
写在前面:
先讲讲ajax中的相关函数,然后结合函数功能来具体分析源代码。
相关函数:
>>ajax全局事件处理程序
| .ajaxStart(handler) | 注册一个ajaxStart事件处理器。当一个Ajax请求开始,并且同时无其它未完成的Ajax请求时,jQuery触发ajaxStart事件。 |
| .ajaxSend(handler) | 注册一个ajaxSend事件处理器。当一个Ajax请求被发送时触发ajaxSend事件。 |
| .ajaxSuccess(handler) | 注册一个ajaxSuccess事件处理器。当一个Ajax请求成功时触发ajaxSuccess事件。 |
| .ajaxError(handler) | 注册一个ajaxError事件处理器。当一个Ajax请求出错时触发ajaxError事件。 |
| .ajaxComplete(handler) | 注册一个ajaxComplete事件处理器。当一个Ajax请求完成时触发ajaxComplete事件。 |
| .ajaxStop(handler) | 注册一个ajaxStop事件处理器。,当一个Ajax请求完成,并且同时无其它未完成的Ajax请求时触发ajaxStop事件。 |
注意:
这六个Ajax全局事件的处理函数都应该注册在document上。
例如: $(document).ajaxSuccess(handler);
ajax选项中的global是全局ajax事件的开关。如果global选项设置为false,上面的所有ajax全局事件都不会被触发。
特别注意的是ajaxStart和ajaxStop事件上面描述的文字的不同之处。
>> Ajax的基本函数
jQuery.ajaxSetup(options) 设置Ajax默认的选项。
options对象包含用来配置ajax请求的key/value键值对。
函数直接扩展了jQuery.ajaxSetting这个对象,这个对象是Ajax请求的默认的配置对象,扩展后对以后的每个Ajax请求都将产生影响。因此非特殊情况不推荐扩展Ajax的默认选项。
Ajax源码中的使用
//扩展jQuery.ajaxSetting默认选项集合
jQuery.ajaxSetup({
accepts: {
script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"
},
contents: {
script: /(?:java|ecma)script/
},
converters: {
"text script": function( text ) {
jQuery.globalEval( text );
return text;
}
}
});上面的代码,扩展了jQuery.ajaxSetting中的三个默认属性,accepts、contents、converters,这三个属性对象添加对script数据类型的支持。后面介绍这三个选项的用途。
jQuery.ajaxPrefilter( )
jQuery.ajaxPrefilter([dataTypes,]handler)
在每个ajax请求开始之前,对请求做前置处理。
dataTypes是包含一个或者多个空格分开的dataType的字符串。 用来限定前置处理应用的Ajax请求的范围。 dataTypes参数可选,默认是”*”,当某个dataType的前置处理函数队列执行完毕后,最终会执行”*”对应的处理函数队列。
handler参数 function(options,originalOptions,jqXHR) 即具体的处理函数,其中options参数代表用户选项集合即originalOptions和默认选项集合即jQuery.ajaxSetting综合后的请求最终使用选项集合,originalOptions代表调用ajax函数时的用户选项集合,jqXHR是jQuery封装的XHR对象,包含相关的属性和方法。
栗子: 在jQuery源码中,Ajax模块有两处使用了这个函数。
// Handle cache's special case and global
//script类型请求的前置处理
//a.默认不使用浏览器缓存
//b.对于跨域请求:使用get方法,并且设置global为false,即不触发全局ajax对象。
jQuery.ajaxPrefilter( "script", function( s ) {
if ( s.cache === undefined ) {
s.cache = false;
}
if ( s.crossDomain ) {
s.type = "GET";
s.global = false;
}
}); // Detect, normalize options and install callbacks for jsonp requests
//对json和jsonp类型ajax请求的前置处理
jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
//省略其它内容...return "script";}注意:
针对某个数据类型dataType,你可以注册多个处理函数。函数会依次执行。
处理函数可以返回一个dataType字符串,此时jQuery不会继续执行队列中的其它后续处理函数,而是将此字符串添加到请求选项的dataTypes头部,并且转而执行此字符串所对应的前置处理程序。
例如上面的代码中,在对json和jsonp的前置处理中,返回”script”,那么script字符串会被添加到options.dataTypes头部(options就是前面提到的请求最终使用的选项集合),并且会跳转到执行”script”对应的前置处理程序。
jQuery.ajaxTransport( )
jQuery.ajaxTransport(dataType,handler)
dataType 表示请求的数据类型。
handler函数,function(options,originalOption,jqXHR) ,函数返回一个对象,这个代表请求此数据类型时,实际使用的完成传输行为的对象。我把它称作传输对象。传输对象应该包含两个方法,send和abort。 jQuery内部会为每个对应此数据类型的Ajax请求创建这个传输对象。
调用过程就像下面这样:
$.ajaxTransport( dataType, function( options, originalOptions, jqXHR ) {
if( /* transportCanHandleRequest */ ) {
return {
send: function( headers, completeCallback ) {
// Send code
},
abort: function() {
// Abort code
}
};
}
});其中,send函数的参数
headers对象 包含请求头的各种设置completeCallback 函数 当传输过程完成时,调用此函数来告诉Ajax传输过程结束。completeCallback接受四个参数 ( status, statusText, responses, headers )其中responses是包含 dataType/value 的对象。例如像这样的{ xml: XMLData, text: textData }这个函数为ajax请求带来了极大的灵活性,你可以定制自己的传输过程。例如,你可以定制一个dataType为”image”的ajax请求
$.ajaxTransport( "image", function( s ) {
if ( s.type === "GET" && s.async ) {
var image;
return {
send: function( _ , callback ) {
image = new Image();
function done( status ) {
if ( image ) {
var statusText = ( status === 200 ) ? "success" : "error",
tmp = image;
image = image.onreadystatechange = image.onerror = image.onload = null;
callback( status, statusText, { image: tmp } );
}
}
image.onreadystatechange = image.onload = function() {
done( 200 );
};
image.onerror = function() {
done( 404 );
};
image.src = s.url;
},
abort: function() {
if ( image ) {
image = image.onreadystatechange = image.onerror = image.onload = null;
}
}
};
}
});注意到上面callback( status, statusText, { image: tmp } ); callback函数的response参数值是{image:tmp}, image对应数据类型。
jQuery的Ajax模块源代码中,有两处调用了ajaxTransport函数。
一种用来生成是Ajax默认的传输对象。
jQuery.ajaxTransport(function( s ) {//创建"*"对应的transport,即默认处理所有请求的transport//代码省略});上面的ajaxTransport调用省略了dataType参数,此时创建的就是”*”对应的传输过程,即默认使用的传输过程。
另外一种情况,ajax对于跨域的”script”数据类型的请求,使用特殊的传输对象。
// Bind script tag hack transport
//请求script文件使用的传输对象。
jQuery.ajaxTransport( "script", function(s) { // This transport only deals with cross domain requests
//只处理跨域的script数据类型//可以看到跨域的script文件是通过HTML的script标签请求并执行。
if ( s.crossDomain ) { var script,
head = document.head || jQuery("head")[0] || document.documentElement; return { send: function( _, callback ) { script = document.createElement("script"); script.async = true; if ( s.scriptCharset ) {
script.charset = s.scriptCharset;
} script.src = s.url; // Attach handlers for all browsers
//isAbort参数在下面定义的abort方法中手动调用script.onload函数时设为true
//IE的 script 元素支持onreadystatechange事件,不支持onload事件。
//FF的script 元素不支持onreadystatechange事件,只支持onload事件。
script.onload = script.onreadystatechange = function( _, isAbort ) {
//isAbort时,做清除script的处理
//!script.readyState 说明是在FF下面,此时表明load完成
///loaded|complete/.test( script.readyState )表明在IE下需要检测到readyState为loaded或者complete时,才算load完成
if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) { // Handle memory leak in IE
script.onload = script.onreadystatechange = null; // Remove the script
if ( script.parentNode ) {
script.parentNode.removeChild( script );
} // Dereference the script
script = null; // Callback if not abort
if ( !isAbort ) {
callback( 200, "success" );
}
}
}; // Circumvent IE6 bugs with base elements (#2709 and #4378) by prepending
// Use native DOM manipulation to avoid our domManip AJAX trickery
head.insertBefore( script, head.firstChild );
}, abort: function() {
if ( script ) {
script.onload( undefined, true );
}
}
};
}
});注意:
与前面讲的ajaxPrefilter相似,每种数据类型可以定义多个传输函数。如果其中一个函数返回了传输对象,那么就终止函数队列的调用。如果具体数据类型未得到传输对象,最后会调用“*”对应的传输函数队列。
jQuery.ajax()
放在单独的一个篇文章里
>> ajax相关的快捷方法
jQuery.post()
jQuery.get()
jQuery.getJSON()
jQuery.getScript()
.load()
另起一片文章讲。
>> Ajax源代码的架构和流程分析
另起一片文章讲。
>>ajax返回jqXHR对象分析,关于Deferred对象
另起一片文章讲。
最后: 第一次写,写文章果然麻烦,感觉内容量好大,一时半会儿写不完,还是分多个板块来写吧。先直接贴Ajax模块的源代码(带注解)。
jQuery源码 Ajax模块分析的更多相关文章
- jQuery源码解读-事件分析
最原始的事件注册 addEventListener方法大家应该都很熟悉,它是Html元素注册事件最原始的方法.先看下addEventListener方法签名: element.addEventList ...
- jQuery源码dom ready分析
一.前言 在平时开发web项目时,我们使用jquery框架时,可能经常这样来使用$(document).ready(fn),$(function(){}),这样使用的原因是在浏览器把DOM树渲染好之前 ...
- jquery源码ajax分析
http://www.cnblogs.com/aaronjs/p/3683925.html
- jQuery源码解析资源便签
最近开始解读jQuery源码,下面的链接都是搜过来的,当然妙味课堂 有相关的一系列视频,长达100多期,就像一只蜗牛慢慢爬, 至少品读三个框架,以后可以打打怪,自己造造轮子. 完全理解jQuery源代 ...
- jQuery源码分析学习--资料收集--更新中
1.逐行分析jQuery源码的奥秘 - 网易云课堂 http://study.163.com/course/courseMain.htm?courseId=465001#/courseDetail? ...
- jQuery源码-dom操作之jQuery.fn.html
写在前面 前面陆陆续续写了jQuery源码的一些分析,尽可能地想要cover里面的源码细节,结果导致进度有些缓慢.jQuery的源码本来就比较晦涩,里面还有很多为了解决兼容问题很引入的神代码,如果不g ...
- jQuery源码分析系列
声明:本文为原创文章,如需转载,请注明来源并保留原文链接Aaron,谢谢! 版本截止到2013.8.24 jQuery官方发布最新的的2.0.3为准 附上每一章的源码注释分析 :https://git ...
- [转] jQuery源码分析-如何做jQuery源码分析
jQuery源码分析系列(持续更新) jQuery的源码有些晦涩难懂,本文分享一些我看源码的方法,每一个模块我基本按照这样的顺序去学习. 当我读到难度的书或者源码时,会和<如何阅读一本书> ...
- [转]jQuery源码分析系列
文章转自:jQuery源码分析系列-Aaron 版本截止到2013.8.24 jQuery官方发布最新的的2.0.3为准 附上每一章的源码注释分析 :https://github.com/JsAaro ...
随机推荐
- 案例1.通过Jquery来处理复选框
实现以下功能: 1:选中第一个复选框,那么下面所有的复选框都选中,去除选中第一个复选框,下面的都不选中 2:当点击全选按钮,上面足球.篮球.游泳.唱歌 全部选中 3:当点击全不选按钮,上面四个全部取消 ...
- Ubuntu14.10搭建C++开发环境
方法一:1、安装Eclipsesudo apt-get install eclipse2、安装Eclipse CDTsudo apt-get install eclipse-cdt3、安装Autoto ...
- mysql数据库导出模型到powerdesigner,PDM图形窗口中显示数据列的中文注释
1,mysql数据库导出模型到powerdesigner 2,CRL+Shift+X 3,复制以下内容,执行 '******************************************** ...
- 命令行操作svn和git和git
前几天在写代码的时候电脑突然坏掉,老大交代的任务没完成,非常痛恨自己用svn或者git保存代码,相信很多程序员遇到过,硬盘坏掉,存在硬盘中的代码丢失,无法找回的问题,svn和git可谓程序员界的福音, ...
- JS中常遇到的浏览器兼容问题和解决方法
今天整理了一下浏览器对JS的兼容问题,希望能给你们带来帮助,我没想到的地方请留言给我,我再加上: 常遇到的关于浏览器的宽高问题: //以下均可console.log()实验 var winW=docu ...
- 验证mongodb副本集并实现自动切换primary~记录过程
接 验证mongodb主从复制过程 1.创建数据目录 同 验证mongodb主从复制过程 的实验一样,本次实验也是采用直接指定启动参数来启动mongodb数据库,本次实验我们需要启动三个数据库,为了与 ...
- PHP基础知识之流程控制的替代语法
PHP 提供了一些流程控制的替代语法,包括 if,while,for,foreach 和 switch. 替代语法的基本形式是把左花括号({)换成冒号(:),把右花括号(})分别换成 endif;,e ...
- web Api 返回json 的两种方式
web api写api接口时默认返回的是把你的对象序列化后以XML形式返回,那么怎样才能让其返回为json呢,下面就介绍两种方法: 方法一:(改配置法) 找到Global.asax文件,在Applic ...
- Chrome必备的扩展
Devtools Terminal ——浏览器终端.牛逼的不得了! LiveReload——为官方 LiveReload 应用程序(Mac 和 Windows)和第三方,例如 guard-livere ...
- linux下打包zip文件
zip [参数] [打包后的文件名] [打包的目录路径] linux zip命令参数列表:-a 将文件转成ASCII模式-F 尝试修复损坏的压缩文件 -h 显示帮助界面-m 将文件压 ...