jQuery源码分析-15AJAX-类型转换器
<!--[if !supportLists]-->15.5 <!--[endif]-->AJAX中的类型转换器
前置过滤器、 请求分发器、类型转换器是读懂jQuery AJAX实现的关键,可能最难读的又是类型转换器。除此之外的源码虽然同样的让人纠结,但相较而言并不算复杂。
类型转换器将服务端响应的responseText或responseXML,转换为请求时指定的数据类型dataType,如果没有指定类型就依据响应头Content-Type自动猜测一个。在分析转换过程之前,很有必要先看看类型转换器的初始化过程,看看支持哪些类型之间的转换。
<!--[if !supportLists]-->15.5.1 <!--[endif]-->类型转换器的初始化
类型转换器ajaxConvert在服务端响应成功后,对定义在jQuery. ajaxSettings中的converters进行遍历,找到与数据类型相匹配的转换函数,并执行。我们先看看converters的初始化过程,对类型类型转换器的功能有个初步的认识。jQuery. ajaxSettings定义了所有AJAX请求的默认参数,我们暂时先忽略其他属性、方法的定义和实现:
jQuery.extend({
// some code ...
// ajax请求的默认参数
ajaxSettings: {
// some code ...
// 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
// 类型转换映射,key格式为单个空格分割的字符串:源格式 目标格式
converters: {
// Convert anything to text、
// 任意内容转换为字符串
// window.String 将会在min文件中被压缩为 a.String
"* text": window.String,
// Text to html (true = no transformation)
// 文本转换为HTML(true表示不需要转换,直接返回)
"text html": true,
// Evaluate text as a json expression
// 文本转换为JSON
"text json": jQuery.parseJSON,
// Parse text as xml
// 文本转换为XML
"text xml": jQuery.parseXML
}
}
// some code ...
});
然后在jQuery初始化过程中,对jQuery. ajaxSettings.converters做了扩展,增加了text>script的转换:
// Install script dataType
// 初始化script对应的数据类型
// MARK:AJAX模块初始化
jQuery.ajaxSetup({
accepts: {
script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"
},
contents: {
script: /javascript|ecmascript/
},
// 初始化类型转换器,这个为什么不写在jQuery.ajaxSettings中而要用扩展的方式添加呢?
// 这个转换器是用来出特殊处理JSONP请求的,显然,jQuery的作者John Resig,时时刻刻都认为JSONP和跨域要特殊处理!
converters: {
"text script": function( text ) {
jQuery.globalEval( text );
return text;
}
}
});
初始化过程到这里就结束了,很简单,就是填充jQuery. ajaxSettings.converters。
当一个AJAX请求完成后,会调用闭包函数done,在done中判断本次请求是否成功,如果成功就调用ajaxConvert对响应的数据进行类型转换(闭包函数done在讲到jQuery.ajax()时一并分析):
// 服务器响应完毕之后的回调函数,done将复杂的善后事宜封装了起来,执行的动作包括:
// 清除本次请求用到的变量、解析状态码&状态描述、执行异步回调函数队列、执行complete队列、触发全局Ajax事件
// status: -1 没有找到请求分发器
function done( status, statusText, responses, headers ) {
// 省略代码...
// If successful, handle type chaining
// 如果成功的话,处理类型
if ( status >= 200 && status < 300 || status === 304 ) {
// 如果没有修改,修改状态数据,设置成功
if ( status === 304 ) { 省略代码... }
else {
try {
// 获取相应的数据
// 在ajaxConvert这个函数中,将Server返回的的数据进行相应的转换(js、json等等)
success = ajaxConvert( s, response ); // 注意:这里的succes变为转换后的数据对象!
statusText = "success";
isSuccess = true;
} catch(e) {
// We have a parsererror
// 数据类型转换器解析时出现错误
statusText = "parsererror";
error = e;
}
}
// 非200~300,非304
} else {
// We extract error from statusText
// then normalize statusText and status for non-aborts
// 其他的异常状态,格式化statusText、status,不采用HTTP标准状态码和状态描述
error = statusText;
if( !statusText || status ) {
statusText = "error";
if ( status < 0 ) {
status = 0;
}
}
}
// 省略代码...
}
<!--[if !supportLists]-->15.5.2 <!--[endif]-->类型转换器的执行过程
类型转换器ajaxConvert根据请求时设置的数据类型,从jQuery. ajaxSettings.con
补充:web前端 , JavaScript ,