6-11 类型转化器
本节编程练习不计算学习进度,请电脑登录imooc.com操作

类型转化器

什么是类型转化器?

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)

 

任务

  1. <!doctype html>
  2. <html>
  3. <head>
  4. <meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
  5. <title>类型转化器</title>
  6. <script src="http://code.jquery.com/jquery-latest.js"></script>
  7. </head>
  8. <body>
  9.  
  10.  
  11. <button id="test1">json类型</button>
  12. <button id="test2">xml类型</button>
  13. <ul></ul>
  14. <script type="text/javascript">
  15.  
  16. //执行一个异步的HTTP(Ajax)的请求。
  17. var ajax = $.ajax({
  18. crossDomain :true,
  19. url: 'http://192.168.1.113:8080/github/jQuery/jsonp.php',
  20. data: {
  21. 'action': 'aaron'
  22. },
  23. dataType: 'xml', // 数据类型
  24. jsonp: 'callback', // 指定回调函数名,与服务器端接收的一致,并回传回来
  25. //请求发送前的回调函数,用来修改请求发送前jqXHR
  26. beforeSend: function(xhr) {
  27. xhr.overrideMimeType("text/plain; charset=x-user-defined");
  28. console.log('局部事件beforeSend')
  29. },
  30. //请求完成后回调函数 (请求success 和 error之后均调用)
  31. complete: function() {
  32. console.log('局部事件complete')
  33. },
  34. error: function() {
  35. console.log('局部事件error请求失败时调用此函数')
  36. },
  37. success: function(data) {
  38. console.log('局部事件success',data)
  39. }
  40. })
  41.  
  42. ///////////////////////////////////////////////////
  43. // 有效的数据类型是text, html, xml, json,jsonp,和 script. //
  44. // 如果指定的是text 或 html, 则不会预处理。
  45. // 这些数据被简单地传递给成功处理函数,
  46. // 并通过该jqXHR对象的responseText属性获得的。
  47. ///////////////////////////////////////////////////
  48.  
  49.  
  50. /**
  51. * 服务端返回的一段文本
  52. * @type {String}
  53. */
  54. var data = '{"status":1,"info":"OK"}';
  55. /**
  56. * 服务器返回的xml
  57. * @type {String}
  58. */
  59. var xml = "<root><people><name>慕课网</name><address>北京</address></people></root>";
  60.  
  61. //////////////////////
  62. //dataType 为json的时候 //
  63. //converters =>text json
  64. //////////////////////
  65. function ajaxConvertJSON(data) {
  66. //内部转化成json的对象
  67. var parseJSON = function(data) {
  68. return JSON.parse(data + "");
  69. };
  70. return parseJSON(data)
  71. }
  72.  
  73. //////////////////////
  74. //dataType 为xml的时候 //
  75. //converters =>text xml
  76. //////////////////////
  77. function ajaxConvertXML(data) {
  78. var xml, tmp;
  79. try {
  80. tmp = new DOMParser();
  81. xml = tmp.parseFromString(data, "text/xml");
  82. } catch (e) {
  83. xml = undefined;
  84. }
  85. if (!xml || xml.getElementsByTagName("parsererror").length) {
  86. jQuery.error("Invalid XML: " + data);
  87. }
  88. return xml;
  89. }
  90.  
  91.  
  92. var $ul = $('ul')
  93.  
  94. function show(data) {
  95. $ul.append('<li>' + data + '</li>');
  96. }
  97.  
  98. $("#test1").click(function(){
  99. show(ajaxConvertJSON(data))
  100. })
  101.  
  102. $("#test2").click(function(){
  103. show(ajaxConvertXML(xml))
  104. })
  105.  
  106.  
  107.  
  108. </script>
  109. </body>
  110. </html>
下一节