什么是类型转化器?
jQuery 支持不同格式的数据返回形式,比如 dataType 为 xml、json、jsonp、script、html。但是浏览器的 XMLHttpRequest 对象对数据的响应只有 responseText 与 responseXML 这2种,所以现在我要定义 dataType 为 jsonp,那么所得的最终数据是一个 json 的键值对,所以 jQuery 内部就会默认帮你完成这个转化工作,jQuery 为了处理这种执行后数据的转化,就引入了类型转化器,如果没有指定类型就依据响应头 Content-Type 自动处理数据传输,服务器只能返回字符串形式的,所以如果我们 dataType 为 jsop 或者 json 的时候服务器返回的数据为:
responseText: "{"a":1,"b":2,"c":3,"d":4,"e":5}"
给转化成:
responseJSON: Object
{
a: 1
b: 2
c: 3
d: 4
e: 5
}
服务器的传输返回的只能是 string 类型的数据,但是用户如果通过 jQuery 的 dataType 定义了 json 的格式后,会默认把数据转换成 Object 的形式返回,这就是 jQuery 内部做的智能处理了,jQuery 内把自定义的 dataType 与服务器返回的数据做相对应的映射处理,通过 converters 存储对应的处理句柄,把需要类型转换器 ajaxConvert 在服务端响应成功后,对定义在 jQuery. ajaxSettings 中的 converters 进行遍历,找到与数据类型相匹配的转换函数,并执行。
converters的映射
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
}
除此之外还有额外扩展的一部分 jsonp 的处理,所以其格式就是。
text –> (html,json,script)的处理了
其寓意就是服务器返回的用于只是 string 类型的文本格式,需要转化成用户想要的 dataType 类型的数据:
{"* text": window.String, "text html": true, "text json": jQuery.parseJSON, "text xml": jQuery.parseXML}
类型的转化都是发生在服务器返回数据后,所以对应的就是 ajax 方法中的 done 之后,当然这个 done 方法也是经过请求分发器包装过的,至于为什么要这样处理,上章就已经提到过了,为了处理正常请求与 jsonp 的跨域请求的问题。
所以当 AJAX 请求完成后,会调用闭包函数 done,在 done 中判断本次请求是否成功,如果成功就调用 ajaxConvert 对响应的数据进行类型转换。
所以在此之前需要:
1. 正确分配 dataType 类型,如果用户不设置(空)的情况 2. 需要转化成 converters 映射表对应的格式比如(* text, text html , text xml , text json)
<!doctype html> <html> <head> <meta http-equiv="Content-type" content="text/html; charset=utf-8"/> <title>类型转化器</title> <script src="http://code.jquery.com/jquery-latest.js"></script> </head> <body> <button id="test1">json类型</button> <button id="test2">xml类型</button> <ul></ul> <script type="text/javascript"> //执行一个异步的HTTP(Ajax)的请求。 var ajax = $.ajax({ crossDomain :true, url: 'http://192.168.1.113:8080/github/jQuery/jsonp.php', data: { 'action': 'aaron' }, dataType: 'xml', // 数据类型 jsonp: 'callback', // 指定回调函数名,与服务器端接收的一致,并回传回来 //请求发送前的回调函数,用来修改请求发送前jqXHR beforeSend: function(xhr) { xhr.overrideMimeType("text/plain; charset=x-user-defined"); console.log('局部事件beforeSend') }, //请求完成后回调函数 (请求success 和 error之后均调用) complete: function() { console.log('局部事件complete') }, error: function() { console.log('局部事件error请求失败时调用此函数') }, success: function(data) { console.log('局部事件success',data) } }) /////////////////////////////////////////////////// // 有效的数据类型是text, html, xml, json,jsonp,和 script. // // 如果指定的是text 或 html, 则不会预处理。 // 这些数据被简单地传递给成功处理函数, // 并通过该jqXHR对象的responseText属性获得的。 /////////////////////////////////////////////////// /** * 服务端返回的一段文本 * @type {String} */ var data = '{"status":1,"info":"OK"}'; /** * 服务器返回的xml * @type {String} */ var xml = "<root><people><name>慕课网</name><address>北京</address></people></root>"; ////////////////////// //dataType 为json的时候 // //converters =>text json ////////////////////// function ajaxConvertJSON(data) { //内部转化成json的对象 var parseJSON = function(data) { return JSON.parse(data + ""); }; return parseJSON(data) } ////////////////////// //dataType 为xml的时候 // //converters =>text xml ////////////////////// function ajaxConvertXML(data) { var xml, tmp; try { tmp = new DOMParser(); xml = tmp.parseFromString(data, "text/xml"); } catch (e) { xml = undefined; } if (!xml || xml.getElementsByTagName("parsererror").length) { jQuery.error("Invalid XML: " + data); } return xml; } var $ul = $('ul') function show(data) { $ul.append('<li>' + data + '</li>'); } $("#test1").click(function(){ show(ajaxConvertJSON(data)) }) $("#test2").click(function(){ show(ajaxConvertXML(xml)) }) </script> </body> </html>