dataType 类型的转化
dataType 类型的参数,可以是 xml, json, script, or html 或者干脆为空,那么 jQuery 就需要一个方法去判断当前是属于什么数据处理,就此引入了 ajaxConvert 处理响应转化器,解析出正确的 dataType 类。
response = ajaxConvert(s, response, jqXHR, isSuccess);
分析下 dataType 无法就那么几种情况
1. dataType 为空,自动转化
此时 jQuery 只能根据头部信息来猜测当前需要处理的类型,删除掉通配 dataType,得到返回的 Content-Type。
while (dataTypes[0] === "*") { dataTypes.shift(); if (ct === undefined) { ct = s.mimeType || jqXHR.getResponseHeader("Content-Type"); } }
通过 xhr.getAllResponseHeaders() 得到头部信息,然后去匹配 Content-Type 所有对象的值即可,当然找到这个 Content-Type = “html”,我们还得看看有没有对应处理的方法,如果有就需要替换这个 dataTypes。
看看是不是我们能处理的 Content-Type,比如图片这类二进制类型就不好处理了。
if (ct) { // 实际上能处理的就是text、xml和json for (type in contents) { if (contents[type] && contents[type].test(ct)) { dataTypes.unshift(type); break; } } }
经过这个流程后,dataTypes 本来是 * 就变成了对应的 html了,这是 jquery 内部的自动转化过。
2. dataType开发者指定
xml, json, script, html, jsop类型转换器将服务端响应的 responseText 或 responseXML,转换为请求时指定的数据类型 dataType,如果没有指定类型就依据响应头 Content-Type 自动处理。
类型转换器的执行过程
response = ajaxConvert(s, response, jqXHR, isSuccess);
流程
1.遍历dataTypes中对应的处理规则【"script","json"】 2.制作jqXHR对象的返回数据接口 json: "responseJSON" text: "responseText" xml: "responseXML" 如:jqXHR.responseText: "{"a":1,"b":2,"c":3,"d":4,"e":5}" 3.生成转化器对应的匹配规则,寻找合适的处理器 4.返回处理后的数据response
分析一下特殊的 jsonp 的转化流程,先看看转化对应的处理器。
jsonp
converters["script json"] = function() { if (!responseContainer) { jQuery.error(callbackName + " was not called"); } return responseContainer[0]; };
jsonp 的转化器只是很简单的从 responseContainer 取出了对应的值,所以 responseContainer 肯定在转化之后就应该把数据给转化成数组对象了,当然做源码分析需要一点自己猜想能力,比如 responseContainer 这个数组对象如何而来?
那么我们知道 jsonp 的处理的原理,还是通过加载 script,然后服务器返回一个回调函数,responseContainer 数据就是回调函数的实参,所以需要满足 responseContainer 的处理,必须要先满足脚本先加载,所以我们要去分发器中找对应的加载代码,首先responseContainer 是内部变量,只有一个来源处,在预处理的时候增加一个全局的临时函数,然后代码肯定是执行了这个函数才能把 arguments 参数赋给 responseContainer。
overwritten = window[callbackName]; window[callbackName] = function() { responseContainer = arguments; }; //callbcakName是内部创建的一个尼玛函数名 jQuery203029543792246840894_1403062512436 = function() { responseContainer = arguments; };
我们发送请求:
http://192.168.1.114/yii/demos/test.php?backfunc=jQuery203029543792246840894_1403062512436&action=aaron&_=1403062601515
服务器那边就回调后,执行了 jQuery203029543792246840894_1403062512436(responseContainer ) 所以全局的 callbackName 函数需要在分发器中脚本加载后才能执行,从而才能截取到服务器返回的数据。
请验证,完成请求
由于请求次数过多,请先验证,完成再次请求
打开微信扫码自动绑定
绑定后可得到
使用 Ctrl+D 可将课程添加到书签
举报