博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
第111天:Ajax之jQuery实现方法
阅读量:7095 次
发布时间:2019-06-28

本文共 11946 字,大约阅读时间需要 39 分钟。

由于jQuery中的Ajax方法是用了内置的deferred模块,是Promise模式的一种实现,而我们这里没有讲过,所以我们就不使用这一模式啦。

我们只定义一个Ajax方法,他可以简单的getpostjsonp请求就可以了。

一、jQuery语法格式

1 var ajax = function () { 2      3   //  做一些初始化,定义一些私有函数等 4   5   return function () { 6     // ajax主体代码 7   } 8      9 }()10 11 12 ajax({13   url: myUrl,14   type: 'get',15   dataType: 'json',16   timeout: 1000,17   success: function (data, status) {18     console.log(data)19   },20   fail: function (err, status) {21     console.log(err)22   }23 })

二、初始化属性

Ajax方法需要传递一个对象进去,这个对象中我们可以定义一些我们希望的属性,我们就必须初始一下各种属性

1 //默认请求参数 2   var _options = { 3     url: null,  // 请求连接 4     type: 'GET',  // 请求类型 5     data: null,  // post时请求体 6     dataType: 'text',  // 返回请求的类型,有text/json两种 7     jsonp: 'callback',  // jsonp请求的标志,一般不改动 8     jsonpCallback: 'jsonpCallback',  //jsonp请求的函数名 9     async: true,   // 是否异步10     cache: true,   // 是否缓存11     timeout:null,  // 设置请求超时12     contentType: 'application/x-www-form-urlencoded',13     success: null,  // 请求成功回调函数14     fail: null   // 请求失败回调15   }

三、Ajax主体函数

以上我们定义了一大串请求有关的数据,接下来我们就开始Ajax主体函数的书写,现在的Ajax方法是这样了

1 var ajax = function () { 2  3   //默认请求参数 4   var _options = { 5     url: null, 6     type: 'GET', 7     data: null, 8     dataType: 'text', 9     jsonp: 'callback',10     jsonpCallback: 'jsonpCallback',11     async: true,12     cache: true,13     timeout:null,14     contentType: 'application/x-www-form-urlencoded',15     success: null,16     fail: null17   }18   // ...19   return function (options) {20      // ...21   }22 }()

四、内部继承

我们可以想一下,ajax方法传递一个对象进来,我们需要把我们设置的这个对象上的属性来覆盖掉初始化_options上面的那些属性呢,肯定需要。那下面我们先写一个简单的继承,如下:

1 var ajax = function () { 2  3   //默认请求参数 4   var _options = { 5     url: null, 6     type: 'GET', 7     data: null, 8     dataType: 'text', 9     jsonp: 'callback',10     jsonpCallback: 'jsonpCallback',11     async: true,12     cache: true,13     timeout:null,14     contentType: 'application/x-www-form-urlencoded',15     success: null,16     fail: null17   }18   //  内部使用的继承方法19   var _extend = function(target,options) {20     if( typeof target !== 'object' || typeof options !== 'object' ) {21       return;22     }23     var copy ,clone, name;24     for( name in options ) {25       if(options.hasOwnProperty(name) && !target.hasOwnProperty(name)) {26         target[name] = options[name];27       }28     }29     return target;30   };31 32 33   // ...34   return function (options) {35 36     // 没有传参或者没有url,抛出错误37     if( !options || !options.url ) {38       throw('参数错误!');39     }40 41     // 继承操作42     options.type = options.type.toUpperCase();43     _extend(options,_options);44      // ...45   }46 }()

这个继承方法,我们是把初始化的_options继承到了options,为什么呢?因为我们这个_options对象不在ajax方法内部,我们需要使用它,但我们不能改变他,如果改变了他,下一次使用ajax方法将会崩溃。因此,我们仅仅是把配置的options对象没有的属性设置为初始值。

五、jsonp请求

jsonp请求不是xhr请求,他是将请求url当做script标签的src值插入到页面body中去实现的,我们先把jsonp请求处理一下再开始建立xhr请求的代码吧。

1 var ajax = function () { 2  3   //默认请求参数 4   var _options = { 5     url: null, 6     type: 'GET', 7     data: null, 8     dataType: 'text', 9     jsonp: 'callback',10     jsonpCallback: 'jsonpCallback',11     async: true,12     cache: true,13     timeout:null,14     contentType: 'application/x-www-form-urlencoded',15     success: null,16     fail: null17   }18   //  内部使用的继承方法19   var _extend = function(target,options) {20     if( typeof target !== 'object' || typeof options !== 'object' ) {21       return;22     }23     var copy ,clone, name;24     for( name in options ) {25       if(options.hasOwnProperty(name) && !target.hasOwnProperty(name)) {26         target[name] = options[name];27       }28     }29     return target;30   };31   32   // jsonp处理函数33   function _sendJsonpRequest(url,callbackName,succCallback) {34 35     var script = document.createElement('script');36 37     script.type="text/javascript";38     script.src=url;39 40     document.body.appendChild(script);41     // 如果用户自己定义了回调函数,就用自己定义的,否则,调用success函数42     window[callbackName] = window[callbackName] || succCallback;43 44   }45 46   // ...47   return function (options) {48 49     // 没有传参或者没有url,抛出错误50     if( !options || !options.url ) {51       throw('参数错误!');52     }53 54     // 继承操作55     options.type = options.type.toUpperCase();56     _extend(options,_options);57 58     /*jsonp部分,直接返回*/59     if( options.dataType === 'jsonp' ) {60       var jsonpUrl = options.url.indexOf('?') > -1 ? options.url: options.url +61         '?' + options.jsonp+ '=' + options.jsonpCallback;62 63      return  _sendJsonpRequest(jsonpUrl,options.jsonpCallback,options.success);64       65     }66      // ...67   }68 }()

我们定义了一个_sendJsonpRequest函数,这个函数接收三个参数,第一个是jsonpUrl,第二个是jsonp的回调函数名,第三个是成功回调函数,我们在这个函数内建立一个srcjsonpUrlscript元素插入到body中,同时,确定了回调函数(如果我们定义了jsonpCallback函数就调用它,如果没有就调用success回调,一般情况我们不去定义全局的jsonpCallback函数而传递success回调来完成jsonp请求)。

六、xhr请求处理

好,处理好jsonp请求后,我们开始处理xhr请求了。

1 var ajax = function () {  2   3   //默认请求参数  4   var _options = {  5     url: null,  6     type: 'GET',  7     data: null,  8     dataType: 'text',  9     jsonp: 'callback', 10     jsonpCallback: 'jsonpCallback', 11     async: true, 12     cache: true, 13     timeout:null, 14     contentType: 'application/x-www-form-urlencoded', 15     success: null, 16     fail: null 17   } 18   //  内部使用的继承方法 19   var _extend = function(target,options) { 20     if( typeof target !== 'object' || typeof options !== 'object' ) { 21       return; 22     } 23     var copy ,clone, name; 24     for( name in options ) { 25       if(options.hasOwnProperty(name) && !target.hasOwnProperty(name)) { 26         target[name] = options[name]; 27       } 28     } 29     return target; 30   }; 31    32   // jsonp处理函数 33   function _sendJsonpRequest(url,callbackName,succCallback) { 34  35     var script = document.createElement('script'); 36  37     script.type="text/javascript"; 38     script.src=url; 39  40     document.body.appendChild(script); 41     // 如果用户自己定义了回调函数,就用自己定义的,否则,调用success函数 42     window[callbackName] = window[callbackName] || succCallback; 43  44   } 45    46   // json转化为字符串 47   var _param = function(data) { 48     var str = ''; 49     if( !data || _empty(data)) { 50       return str; 51     } 52     for(var key in data) { 53       str += key + '='+ data[key]+'&' 54     } 55     str = str.slice(0,-1); 56     return str; 57   } 58   //判断对象是否为空 59   var _empty = function(obj) { 60     for(var key in obj) { 61       return false; 62     } 63     return true; 64   } 65  66   // ... 67   return function (options) { 68  69     // 没有传参或者没有url,抛出错误 70     if( !options || !options.url ) { 71       throw('参数错误!'); 72     } 73  74     // 继承操作 75     options.type = options.type.toUpperCase(); 76     _extend(options,_options); 77  78     /*jsonp部分,直接返回*/ 79     if( options.dataType === 'jsonp' ) { 80       var jsonpUrl = options.url.indexOf('?') > -1 ? options.url: options.url + 81         '?' + options.jsonp+ '=' + options.jsonpCallback; 82  83      return  _sendJsonpRequest(jsonpUrl,options.jsonpCallback,options.success); 84        85     } 86      87      //XMLHttpRequest传参无影响 88     var xhr = new (window.XMLHttpRequest || ActiveXObject)('Microsoft.XMLHTTP'); 89     // get搜索字符串 90     var search = ''; 91  92     // 将data序列化 93     var param= _param(options.data) 94  95     if( options.type === 'GET' ) { 96       search = (options.url.indexOf('?') > -1 ? '&' : '?') + param; 97       if(!options.cache) { 98         search += '&radom='+Math.random(); 99       }100       101       param = null;102     }103 104      // ...105   }106 }()

首先,兼容IE创建xhr对象,XMLHttpRequest构造函数传递参数是无影响,然后我们定义了两个辅助变量:searchparam,前者用于get请求的查询字串,后者用于post请求的send内容,我们定义了一个_param方法来讲对象转换为send方法参数的模式,就如你看到的那样,下面我们做了getpost之间合理的searchparam的赋值工作。接下来我们就可以发送请求书写最激动人心的内容了。

最终的代码如下

1 ;  2   3 var ajax = function () {  4   5   //默认请求参数  6   var _options = {  7     url: null,  8     type: 'GET',  9     data: null, 10     dataType: 'text', 11     jsonp: 'callback', 12     jsonpCallback: 'jsonpCallback', 13     async: true, 14     cache: true, 15     timeout:null, 16     contentType: 'application/x-www-form-urlencoded', 17     success: null, 18     fail: null 19   } 20  21  22   // json转化为字符串 23   var _param = function(data) { 24     var str = ''; 25     if( !data || _empty(data)) { 26       return str; 27     } 28     for(var key in data) { 29       str += key + '='+ data[key]+'&' 30     } 31     str = str.slice(0,-1); 32     return str; 33   } 34   //判断对象是否为空 35   var _empty = function(obj) { 36     for(var key in obj) { 37       return false; 38     } 39     return true; 40   } 41  42   var _extend = function(target,options) { 43     if( typeof target !== 'object' || typeof options !== 'object' ) { 44       return; 45     } 46     var copy ,clone, name; 47     for( name in options ) { 48       if(options.hasOwnProperty(name) && !target.hasOwnProperty(name)) { 49         target[name] = options[name]; 50       } 51     } 52     return target; 53   }; 54  55   // 自定义text转化json格式 56   var parseJSON = function(text) { 57     if(typeof text !== 'string') { 58       return; 59     } 60     if( JSON && JSON.parse ) { 61       return JSON.parse(text); 62     } 63     return (new Function('return '+text))(); 64   } 65  66   // jsonp处理函数 67   function _sendJsonpRequest(url,callbackName,succCallback) { 68  69     var script = document.createElement('script'); 70  71     script.type="text/javascript"; 72     script.src=url; 73  74     document.body.appendChild(script); 75     // 如果用户自己定义了回调函数,就用自己定义的,否则,调用success函数 76     window[callbackName] = window[callbackName] || succCallback; 77  78   } 79  80  81   return function (options) { 82  83     // 没有传参或者没有url,抛出错误 84     if( !options || !options.url ) { 85       throw('参数错误!'); 86     } 87  88     // 继承操作 89     options.type = options.type.toUpperCase(); 90     _extend(options,_options); 91  92     /*jsonp部分,直接返回*/ 93     if( options.dataType === 'jsonp' ) { 94       var jsonpUrl = options.url.indexOf('?') > -1 ? options.url: options.url + 95         '?' + options.jsonp+ '=' + options.jsonpCallback; 96  97       _sendJsonpRequest(jsonpUrl,options.jsonpCallback,options.success); 98        99       return;100     }101 102      //XMLHttpRequest传参无影响103     var xhr = new (window.XMLHttpRequest || ActiveXObject)('Microsoft.XMLHTTP');104 105     // get搜索字符串106     var search = '';107 108     // 将data序列化109     var param= _param(options.data)110 111     if( options.type === 'GET' ) {112       search = (options.url.indexOf('?') > -1 ? '&' : '?') + param;113       if(!options.cache) {114         search += '&radom='+Math.random();115       }116       117       param = null;118     }119 120     xhr.open( options.type, options.url + search, options.async );121 122     xhr.onreadystatechange = function() {123       if( xhr.readyState == 4 ) {124         if( xhr.status >= 200 && xhr.status < 300 || xhr.status == 304 ) {125           var text = xhr.responseText;126           // json格式转换127           if(options.dataType == 'json') {128               text = parseJSON(text)129           }130 131           if( typeof options.success === 'function') {132 133             options.success(text,xhr.status)134           }135           136         }else {137 138           if(typeof options.fail === 'function') {139             options.fail('获取失败', 500)140           }141           142         }143       }144     }145 146     xhr.setRequestHeader('content-type',options.contentType);147     // get请求时param时null148     xhr.send(param);149 150     // 如果设置了超时,就定义151     if(typeof options.timeout === 'number') {152       // ie9+153       if( xhr.timeout ) {154         xhr.timeout = options.timeout;155       }else {156         setTimeout(function() {157           xhr.abort();158         },options.timeout)159       }160     }161   }162 163 }()

可以看到,我们很熟悉的xhr代码,在这里,我们需要写一个解析返回字串形成json格式对象的方法parseJSON,类似于jq中的parseJSON方法,如上所示。

我们还需要设置超时代码,如果设置了请求超时,我们就如上定义。

注意:上面代码中,由于懒,设置请求头一行并没有判断是否在post请求下,你可以自己设置

转载于:https://www.cnblogs.com/le220/p/8025028.html

你可能感兴趣的文章
JSON-RPC轻量级远程调用协议介绍及使用
查看>>
video_capture模块分析
查看>>
Bmob移动后端云服务平台--Android从零開始--(二)android高速入门
查看>>
免费的UI素材准备
查看>>
Ubuntu设置显示桌面快捷键
查看>>
TabBarController和其他view无法建立Relationship segue的原因
查看>>
C语言中结构体变量之间赋值
查看>>
javascript精度问题与调整
查看>>
《从零開始学Swift》学习笔记(Day 63)——Cocoa Touch设计模式及应用之单例模式...
查看>>
hdu 3342 Legal or Not (拓扑排序)
查看>>
Dubbo限制大数据传输的解决方案
查看>>
ML学习分享系列(2)_计算广告小窥[中]
查看>>
form怎样正确post文件
查看>>
JVM概述
查看>>
artTemplate子模板include
查看>>
C#模拟POST提交表单(一)--WebClient
查看>>
[Spark][python]从 web log 中提取出 UserID 作为key 值,形成新的 RDD
查看>>
数据结构与算法(周鹏-未出版)-第六章 树-6.5 Huffman 树
查看>>
Zephyr的Shell
查看>>
fpga技能树
查看>>