ajax源码解析-s对象和jqXHR对象

jQuery.ajax( [url,] options )

通过 HTTP 请求加载远程数据。
返回值:$.ajax() 返回jqXHR对象(jqXHR对象:为XMLHttpRequest对象的超集)。可用于手动终止请求abort()、为ajax函数设置额外的回调函数等。

ajax内部实现的两个重要对象:s对象和jqXHR对象。

s对象

s对象由默认设置jQuery.ajaxSettings对象、options参数集合和jQuery.ajaxSetup({})默认设置合并而成s对象。

var s = jQuery.ajaxSetup({}, options)
jQuery.extend({
ajaxSetup: function (target, settings) {
if (settings) {
// Building a settings object
ajaxExtend(target, jQuery.ajaxSettings);
} else {
// Extending ajaxSettings
settings = target;
target = jQuery.ajaxSettings;
}
ajaxExtend(target, settings);
return target;
},
ajaxSettings: {
url: ajaxLocation,
isLocal: rlocalProtocol.test(ajaxLocParts[1]),
global: true,
type: "GET",
contentType: "application/x-www-form-urlencoded",
processData: true,
async: true,
/*
timeout: 0,
data: null,
dataType: null,
username: null,
password: null,
cache: null,
traditional: false,
headers: {},
*/
accepts: {
xml: "application/xml, text/xml",
html: "text/html",
text: "text/plain",
json: "application/json, text/javascript",
"*": allTypes
},
contents: {
xml: /xml/,
html: /html/,
json: /json/
},
responseFields: {
xml: "responseXML",
text: "responseText"
},
// List of data converters
// 1) key format is "source_type destination_type" (a single space in-between)
// 2) the catchall symbol "*" can be used for source_type
converters: {
// Convert anything to text
"* text": window.String,
// Text to html (true = no transformation)
"text html": true,
// Evaluate text as a json expression
"text json": jQuery.parseJSON,
// Parse text as xml
"text xml": jQuery.parseXML
},
// For options that shouldn't be deep extended:
// you can add your own custom options here if
// and when you create one that shouldn't be
// deep extended (see ajaxExtend)
flatOptions: {
context: true,
url: true
}
},
})
参数名 描述
可由ajax的options参数设置
url (默认: 当前页地址) 要请求的目的URL地址。
username password 用于响应HTTP访问认证请求的用户名及密码
type (默认: “GET”) 请求方式 (“POST” 或 “GET”)。注意:其它 HTTP 请求方法,如 PUT 和 DELETE 也可以使用,但仅部分浏览器支持。
dataType 预期服务器返回的数据类型。如果不指定,jQuery将自动根据 HTTP 包 MIME 信息来智能判断,比如 XML MIME 类型就被识别为 XML。随后服务器端返回的数据会根据这个值解析后,传递给回调函数。
必须确保网页服务器报告的 MIME 类型与我们选择的dataType所匹配。比如说,XML的话,服务器端就必须声明 text/xml 或者 application/xml 来获得一致的结果。
可用值:
1.”xml”返回 XML 文档,可用jQuery处理。
2.”html”返回纯文本 HTML 信息;包含的 script 标签会在插入dom时执行。
3.”script”返回纯文本 JavaScript 代码,常常用于跨域请求。不会触发全局事件和局部事件;只支持GET方式(POST请求会自动转化为GET请求);默认不启用缓存(cache:false)
4.”json”返回 JSON 数据。JSON 数据是一种能很方便通过 JavaScript 解析的结构化数据。
5.”jsonp”JSONP 格式,用于跨域请求。6.”text”返回纯文本字符串
其中,text 和 xml 类型返回的数据不会经过处理。数据仅仅简单的将XMLHttpRequest的responseText或responseHTML属性传递给 success 回调函数。
如果指定了 script 或者jsonp类型,那么当从服务器接收到数据时,实际上是用了script标签而不是XMLHttpRequest对象。
这种情况下,$.ajax() 不再返回一个XMLHttpRequest对象,并且也不会传递事件处理函数,比如beforeSend。
contentType (默认: “application/x-www-form-urlencoded”)标明发送或者接收的实体的MIME类型。当“非GET或HEAD请求”的HTTP请求时,会被设置为HTTP头请求信息。
mimeType 多用途互联网邮件扩展(MIME,Multipurpose Internet Mail Extensions);用于重写服务器端响应的MIME类型。
data 发送到服务器的数据。可以是一个查询字符串,比如 key1=value1&key2=value2 ,也可以是一个映射,比如 {key1: ‘value1’, key2: ‘value2’} 。如果使用了后者的形式,则数据在发送前会通过jQuery.param()函数转换成查询字符串。这个处理过程也可以通过设置processData选项为false来回避。
processData (默认: true) 默认情况下,发送到服务器的数据(即data参数)将被转换为字符串以配合默认内容类型 “application/x-www-form-urlencoded”。如果要发送 DOM 树信息或其它不希望转换的信息,请设置为 false。
jQuery中的处理方式:1)
async (默认: true) 默认设置下,所有请求均为异步请求。如果需要发送同步请求,请将此选项设置为 false。注意,同步请求将锁住浏览器,用户其它操作必须等待请求完成才可以执行。
timeout 设置请求超时时间(毫秒)。通过setTimeout(fn,time)实现。
cache (默认: true)dataType为 script 和jsonp时默认为 false。设置为 false 将不缓存此页面。
当使用GET或HEAD方式发送请求时要添加时间戳参数 (net Date()).getTime() 来保证每次发送的URL不同, 可以避免浏览器缓存.(只有GET和HEAD方式的请求浏览器才会缓存)
jQuery中的处理方式:2)
ifModified (默认: false) 仅在服务器数据改变时获取新数据。通过响应头If-Modified-Since、IF-None-Match和请求头Last-Modified、Etag提高GET或HEAD方式请求效率。(只有GET和HEAD方式的请求浏览器才会缓存)
global (默认: true) 是否触发全局 AJAX 事件。设置为 false 将不会触发全局AJAX 事件:ajaxStart、ajaxSend、ajaxSuccess、ajaxError、ajaxComplete、ajaxStop。(比如请求频繁时可禁用全局AJAX事件提高效率)
context (默认:true) 这个对象用于设置Ajax相关回调函数的上下文,让回调函数内this指向这个对象。如果不设定这个参数,那么回调函数中的this就指向调用本次AJAX请求时传递的options参数载体“s对象”。但对于全局Ajax事件来说,this都是指向全局事件所绑定的元素。
jsonp 指定获得jsonp回调函数名的参数名(默认为:callback)。这个值用来替代URL中”callback=?”里的”callback”部分,比如{jsonp:’onJsonPLoad’}会替换为将”onJsonPLoad=?”传给服务器。
jsonpCallback 为jsonp请求指定一个回调函数名。jsonpCallback参数一般为字符串,也可接收函数(该函数返回字符串)。默认情况下生成随机函数名:”jQuery” + ( jQuery.fn.jquery + Math.random() ).replace( /\D/g, “” ) + jQuery.now()
crossDomain (默认:null)false:同域请求;true跨域请求。倘若crossDomain标识为null,则jQuery会自动根据本地url、端口来解析。可以根据需求直接赋值来提高性能。
通常情况下由服务器自动解析即可,但如果你想在同一域中强制跨域请求(像JSONP一样),那么将crossDomain为true,这允许你将服务器端重定向到另一个域。
scriptCharset 只有当请求时dataType为”jsonp”或”script”,并且type是”GET”才会用于修改charset。
因为此时是动态创建script来完成脚本加载,但是如果js中的编码与页面的编码不一致时,js可能加载失败或者显示乱码或者IE下报某符号错误。设置此参数就相当于为script标签设置charset属性。
hearders (默认:{}) 设置HTTP请求头数据”{键:值}”。此设置发生在:jQuery所有影响HTTP头的参数(options)设置之后,beforeSend回调函数之前。
statusCode (默认:{}) 定义一组HTTP状态码与回调函数的映射,当响应的状态码有匹配statusCode则会触发对应回调函数。例如,如果响应状态是404,将触发以下警报:
jQuery中定义:3)
traditional 如果你想要用传统的方式来序列化数据,那么就设置为true。请参考$.param()深度递归详解
xhrFields 声明附加到XMLHttpRequest对象的自定义“key-value”数组。例如,如果需要的话,你可以用它来设置跨域的withCredentials为true,即:
xhrFields: { withCredentials: true }
5个局部事件 beforeSend、dataFilter、success、error、complete。(详见后面事件介绍部分)
由ajax函数内部解析或内部提供
dataTypes 由dataType按空格拆分所得。
isLocal 根据协议确定当前url请求的是否为本地请求。
jQuery中定义默认值为:4)
hasContent 非GET或HEAD请求为true,用于处理data和contentType参数。
contents 一个”{类型字符串:正则表达式}”的对象,倘若dataTypes[0]为“*”时,用contents中的正则表达式去匹配contentType,匹配成功则用“类型字符串”覆盖dataTypes[0]。
jQuery内部定义如下:5)
accepts 浏览器能够处理的媒体类型,其值取决于dataTypes[0]参数。
jQuery内部定义如下:6)
responseFields jqXHR超集设置“数据类型:属性”对应关系,在返回响应数据时,用于确定创建哪个属性变量。
jQuery中定义如下:7)
converters 存储数据类型对应的转换器,根据dataTypes获取对应转换器,用于对响应数据response进行处理。该处理发生在dataFilter回调函数之后。
jQuery中定义如下:8)

jQuery内部实现方式

1) s.processData

if ( s.data&&s.processData&&typeofs.data !== "string" ) {
s.data = jQuery.param(s.data, s.traditional );
}

2)s.cache

if ( s.cache === false ) {
var ts = jQuery.now(),
// rts = /([?&])_=[^&]*/尝试替换
ret = s.url.replace( rts, "$1_=" + ts );
// rquery = /\?/如果没有替换任何内容,则把时间戳加到url最后
s.url = ret + ( ( ret === s.url ) ? ( rquery.test( s.url ) ? "&" : "?" ) + "_=" + ts : "" );
}

3)statusCode

$.ajax({
statusCode: {404: function() {
alert('page not found');
}
});

4)isLocal

isLocal:/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/.test(/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/.exec(url))

5)contents

contents: {
xml: /xml/,
html: /html/,
json: /json/,
script: /javascript|ecmascript/
}

6)accepts

accepts: {
xml: "application/xml, text/xml",
html: "text/html",
text: "text/plain",
json: "application/json, text/javascript",
script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript",
"*": allTypes // dataTypes[0]匹配不上时取此值
}

7)responseFields

responseFields: {
xml: "responseXML",
text: "responseText"
}

8)converters

converters: {
"* text": window.String,
"text html": true,
"text json": jQuery.parseJSON,
"text xml": jQuery.parseXML,
"text script": function( text ) {
jQuery.globalEval( text ); // 执行脚本
return text;
}
}

jqXHR对象

jqXHR对象为不同浏览器内置的XMLHttpRequest提供了一致的超集。对于XMLHttpRequest之外的传输机制,比如JSONP请求,jXHR对象也可以进行处理。
超集与真子集:如果一个集合S2中的每一个元素都在集合S1中,且集合S1中可能包含S2中没有的元素,则集合S1就是S2的一个超集。 S1是S2的超集,则S2是S1的真子集,反之亦然。
jqXHR对象我们常常使用如下成员,这些成员主要用于ajax的全局事件和局部事件,并且做为$.ajax()函数返回值返回。

jqXHR:{
readyState
,setRequestHeader: function( name, value )
,getAllResponseHeaders: function()
,getResponseHeader: function( key )
,overrideMimeType: function( type )
,abort: function( statusText )
,responseText
,responseXML
}

另外,jqXHR的全部成员如下:
image
1.在图中我们看到一些陌生的函数,比如:done()、fail()、promise()、isResolve()、isRejected()、then()、always()、progress()等,都是jQuery的deferred对象API。
开发网站的过程中,我们经常遇到某些耗时很长的javascript操作。其中,既有异步的操作(比如ajax读取服务器数据),也有同步的操作(比如遍历一个大型数组),它们都不是立即能得到结果的。
2.通常的做法是,为它们指定回调函数(callback)。即事先规定,一旦它们运行结束,应该调用哪些函数。但是,在回调函数方面,jQuery的功能非常弱。为了改变这一点,jQuery开发团队就设计了deferred对象。
简单说,deferred对象就是jQuery的回调函数解决方案。在英语中,defer的意思是”延迟”,所以deferred对象的含义就是”延迟”到未来某个点再执行。 它解决了如何处理耗时操作的问题,对那些操作提供了更好的控制,以及统一的编程接口。
更专业的资源:jQuery的deferred对象详解

sunbaixin wechat
欢迎您扫一扫上面的微信公众号,订阅我的博客!