简单介绍不用库(框架)自己写ajax(2)

var $ = (function(){ //辅助函数 序列化参数 function param(data){ //.. } function ajax(opts){ var _opts = { url : 'https://www.jb51.net/', //发送请求URL地址 type : 'GET', //发送请求的方式 GET(默认), POST dataType : '', //预期服务器返回的数据类型 xml, html, text, json, jsonp, script data : null, //发送的数据 'key=value&key=value', {key:value,key:value} async : true, //异步请求 ture(默认异步), false cache : true, //缓存 ture(默认缓存), false timeout : 5, //超时时间 默认5秒 load : function(){}, //请求加载中 error : function(){}, //请求出错时 success : function(){}, //请求成功时 complete : function(){} //请求完成之后(不论成功或失败) }, aborted = false, key, xhr = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP'); for(key in opts) _opts[key] = opts[key]; /* if(_opts.dataType.toLowerCase() === 'script'){ //.. } if(_opts.dataType.toLowerCase() === 'jsonp'){ //.. } */ if(_opts.type.toUpperCase() === 'GET'){ if(param(_opts.data) !== ''){ _opts.url += (_opts.url.indexOf('?') < 0 ? '?' : '&') + param(_opts.data); } !_opts.cache && ( _opts.url += (_opts.url.indexOf('?') < 0 ? '?' : '&') + '_='+(+new Date()) ); } function checkTimeout(){ if(xhr.readyState !== 4){ aborted = true; xhr.abort(); } } setTimeout(checkTimeout, _opts.timeout*1000); xhr.onreadystatechange = function(){ if( xhr.readyState !== 4 ) _opts.load && _opts.load(xhr); if( xhr.readyState === 4 ){ var s = xhr.status, xhrdata; if( !aborted && ((s >= 200 && s < 300) || s === 304) ){ switch(_opts.dataType.toLowerCase()){ case 'xml': xhrdata = xhr.responseXML; break; case 'json': xhrdata = window.JSON && window.JSON.parse ? JSON.parse(xhr.responseText) : eval('(' + xhr.responseText + ')'); break; default: xhrdata = xhr.responseText; } _opts.success && _opts.success(xhrdata,xhr); }else{ _opts.error && _opts.error(xhr); } _opts.complete && _opts.complete(xhr); } }; xhr.open(_opts.type,_opts.url,_opts.async); if(_opts.type.toUpperCase() === 'POST'){ xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded'); } xhr.send(_opts.type.toUpperCase() === 'GET' ? null : param(_opts.data)); } return { ajax: ajax } })();

  定义好了参数选项,来分析一下。其中 dataType 是整个ajax的重点,代码的简单或者复杂都在它了。

  在这里dataType为预期服务器返回的数据类型:xml, html, text, json, jsonp, script

  1. 为xml时,来自服务器的响应是XML,使用 responseXML 属性获取返回的数据

  2. 为html、text、json时,使用 responseText 属性获取返回的数据

      a. 为html时,返回纯文本HTML信息,其中包含的script标签是否要在插入dom时执行 ( 代码复杂度+3 )

      b. 为json时,  返回JSON数据,要安全、要便捷、要兼容  ( 代码复杂度+2 )

  3. 为jsonp时,一般跨域才用它,不用原来的ajax请求了,用创建script法( 代码复杂度+2 )

  4. 为script时:  要跨域时,不用原来的ajax请求了,用创建script法( 代码复杂度+1 ); 不跨域,返回纯文本JavaScript代码, 使用 responseText 属性获取返回的数据 ( 代码复杂度+1 )

  其中,在html片段中的script标签、jsonp、script,都要用到创建script标签的方式。

  处理dataType为json

xhrdata = window.JSON && window.JSON.parse ? JSON.parse(xhr.responseText) : eval('(' + xhr.responseText + ')');

  这是最简单的处理方式了,要JSON兼容,可以用json2.js。

  处理dataType为jsonp

  jsonp是要通过script标签来请求跨域的,先了解下流程:

简单介绍不用库(框架)自己写ajax

  这上图中 a.html中请求了   (在ajax程序中请求url就是这个链接),在b.php中读取了传过来的参数 callback=add  根据获取到的参数值(值为add),以JS语法生成了函数名,并把json数据作为参数传入了这个函数,返回以JS语法生成的文档给a.html,a.html解析并执行返回的JS文档,调用了定义好的add函数。

  在程序中一般采用更通用的方式去调用,比如下面这个广泛使用的loadJS函数:

function loadJS(url, callback) { var doc = document, script = doc.createElement('script'), body = doc.getElementsByTagName('body')[0]; script.type = 'text/javascript'; if (script.readyState) { script.onreadystatechange = function() { if (script.readyState == 'loaded' || script.readyState == 'complete') { script.onreadystatechange = null; callback && callback(); } }; } else { script.onload = function() { callback && callback(); }; } script.src = url; body.appendChild(script); }

  这样把请求的url,传入loadJS函数,得到一样的结果。

复制代码 代码如下:


loadJS('http://www.b.com/b.php?callback=add');


内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wfyjfw.html