欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

模仿JQuery封装ajax功能

程序员文章站 2022-07-09 20:40:58
需求分析 因为有时候想提高性能,只需要一个ajax函数,不想引入较大的jq文件,尝试过axios,可是get方法不支持多层嵌套的json,post方式后台接收方式似乎要变。。也许是我不太会用吧。。其实换个方式接收也没什么,只是习惯了JQ序列化参数。所以上网搜集了很多资料,同时也进一步了解了一点JQ。 ......

需求分析

  因为有时候想提高性能,只需要一个ajax函数,不想引入较大的jq文件,尝试过axios,可是get方法不支持多层嵌套的json,post方式后台接收方式似乎要变。。也许是我不太会用吧。。其实换个方式接收也没什么,只是习惯了jq序列化参数。所以上网搜集了很多资料,同时也进一步了解了一点jq。以下代码很多来自于网上,自己整合了一下。

 

封装代码

 

 

  1 var ajax = {};
  2 (function($) {
  3 
  4     function ajax(options) {
  5         var str;
  6         var xmlhttprequest;
  7         var timer;
  8         if (window.xmlhttprequest) {
  9             xmlhttprequest = new xmlhttprequest();
 10         } else {
 11             xmlhttprequest = new activexobject("microsoft.xmlhttp");
 12         }
 13         options = object.assign({}, { type: "get", processdata: true, contenttype: "application/x-www-form-urlencoded" }, options);
 14         if (options.type.touppercase() !== "get") {
 15             xmlhttprequest.open(options.type.touppercase(), options.url, true);
 16             xmlhttprequest.setrequestheader("content-type", options.contenttype);
 17             if (options.processdata) {
 18                 str = param(options.data);
 19             } else {
 20                 str = options.data;
 21             }
 22             xmlhttprequest.send(str);
 23         } else {
 24             str = param(object.assign(urlorquerytoobject(options.url), options.data));
 25             if (options.url.indexof("?") !== -1) {
 26                 options.url = options.url.substr(0, options.url.indexof("?"));
 27             }
 28             xmlhttprequest.open("get", options.url + "?" + str, true);
 29             xmlhttprequest.send(null);
 30         }
 31         xmlhttprequest.onreadystatechange = function() {
 32             if (xmlhttprequest.readystate === 4) {
 33                 clearinterval(timer);
 34                 if (xmlhttprequest.status === 200) {
 35                     try {
 36                         // 如果是json格式,自动转换为json对象
 37                         options.success(json.parse(xmlhttprequest.responsetext));
 38                     } catch (e) {
 39                         options.success(xmlhttprequest.responsetext);
 40                     }
 41                 } else if (options.error) {
 42                     if (xmlhttprequest.status === 304) {
 43                         options.error(xmlhttprequest, "notmodified");
 44                     } else {
 45                         options.error(xmlhttprequest, xmlhttprequest.statustext);
 46                     }
 47                 }
 48             }
 49         };
 50         //判断是否超时
 51         if (options.timeout) {
 52             timer = settimeout(function() {
 53                 if (options.error) {
 54                     options.error(xmlhttprequest, "timeout");
 55                 }
 56                 xmlhttprequest.abort();
 57             }, options.timeout);
 58         }
 59     }
 60 
 61     // 把url中的查询字符串转为对象,主要是想当方式为get时,用data对象的参数覆盖掉url中的参数
 62     function urlorquerytoobject(urlorquery) {
 63         var queryarr = [];
 64         var urlsplit = urlorquery.split("?");
 65         queryarr[0] = urlsplit[0];
 66         if (urlsplit[1]) {
 67             queryarr[0] = urlsplit[1];
 68         }
 69         queryarr = queryarr[0].split("&");
 70         var obj = {};
 71         var i = 0;
 72         var temp;
 73         var key;
 74         var value;
 75         for (i = 0; i < queryarr.length; i += 1) {
 76             temp = queryarr[i].split("=");
 77             key = temp[0];
 78             value = temp[1];
 79             obj[key] = value;
 80         }
 81         return obj;
 82     }
 83 
 84     // 序列化参数
 85     // 转载自 https://www.jianshu.com/p/0ca22d53feea
 86     function param(obj, traditional) {
 87 
 88         if (traditional === "undefined") { traditional = false; }
 89         var
 90             rbracket = /\[\]$/,
 91             op = object.prototype,
 92             ap = array.prototype,
 93             aeach = ap.foreach,
 94             ostring = op.tostring;
 95 
 96         function isfunction(it) {
 97             return ostring.call(it) === "[object function]";
 98         }
 99 
100         function isarray(it) {
101             return ostring.call(it) === "[object array]";
102         }
103 
104         function isobject(it) {
105             return ostring.call(it) === "[object object]";
106         }
107 
108         function buildparams(prefix, obj, traditional, add) {
109             var name;
110             if (isarray(obj)) {
111                 // serialize array item.
112                 aeach.call(obj, function(v, i) {
113                     if (traditional || rbracket.test(prefix)) {
114                         // treat each array item as a scalar.
115                         add(prefix, v);
116                     } else {
117                         // item is non-scalar (array or object), encode its numeric index.
118                         buildparams(
119                             prefix + "[" + (typeof v === "object" && v != null ? i : "") + "]",
120                             v,
121                             traditional,
122                             add
123                         );
124                     }
125                 });
126             } else if (!traditional && isobject(obj)) {
127                 // serialize object item.
128                 for (name in obj) {
129                     buildparams(prefix + "[" + name + "]", obj[name], traditional, add);
130                 }
131             } else {
132                 // serialize scalar item.
133                 add(prefix, obj);
134             }
135         }
136         // serialize an array of form elements or a set of
137         // key/values into a query string
138         function jollyparam(a, traditional) {
139             var prefix,
140                 s = [],
141                 add = function(key, valueorfunction) {
142                     // if value is a function, invoke it and use its return value
143                     var value = isfunction(valueorfunction) ? valueorfunction() : valueorfunction;
144                     s[s.length] = encodeuricomponent(key) + "=" +
145                         encodeuricomponent(value == null ? "" : value);
146                 };
147             // if an array was passed in, assume that it is an array of form elements.
148             if (isarray(a)) {
149                 // serialize the form elements
150                 aeach.call(a, function(item) {
151                     add(item.name, item.value);
152                 });
153             } else {
154                 // if traditional, encode the "old" way (the way 1.3.2 or older
155                 // did it), otherwise encode params recursively.
156                 for (prefix in a) {
157                     buildparams(prefix, a[prefix], traditional, add);
158                 }
159             }
160             // return the resulting serialization
161             return s.join("&");
162         }
163         return jollyparam(obj, traditional);
164     }
165 
166     // 为避免 object.assign 不能使用
167     // 转载自 https://developer.mozilla.org/zh-cn/docs/web/javascript/reference/global_objects/object/assign
168     if (typeof object.assign != "function") {
169         // must be writable: true, enumerable: false, configurable: true
170         object.defineproperty(object, "assign", {
171             value: function assign(target, varargs) { // .length of function is 2
172                 "use strict";
173                 if (target == null) { // typeerror if undefined or null
174                     throw new typeerror("cannot convert undefined or null to object");
175                 }
176                 var to = object(target);
177                 for (var index = 1; index < arguments.length; index++) {
178                     var nextsource = arguments[index];
179                     if (nextsource != null) { // skip over if undefined or null
180                         for (var nextkey in nextsource) {
181                             // avoid bugs when hasownproperty is shadowed
182                             if (object.prototype.hasownproperty.call(nextsource, nextkey)) {
183                                 to[nextkey] = nextsource[nextkey];
184                             }
185                         }
186                     }
187                 }
188                 return to;
189             },
190             writable: true,
191             configurable: true
192         });
193     }
194 
195     $ = {
196         get: function(url, data, success) {
197             return ajax({ url: url, data: data, success: success });
198         },
199         post: function(url, data, success) {
200             return ajax({ type: "post", url: url, data: data, success: success });
201         },
202         ajax: function(options) { return ajax(options); },
203         param: function(obj, traditional) { return param(obj, traditional); },
204         urlorquerytoobject: function(urlorquery) { return urlorquerytoobject(urlorquery); }
205     };
206 
207     // 满足 jquery 的使用习惯
208     if (typeof window.$ === "undefined") {
209         window.$ = $;
210     }
211 })(ajax);

 

用法


高度模仿jq。

 1 // get请求
 2 $.get("", {}, function(data) {})
 3 
 4 // post请求
 5 $.post("", {}, function(data) {})
 6 
 7 // 更完整的ajax
 8 $.ajax({
 9     type: "post",
10     // 非必须,默认 get
11     url: "",
12     data: {},
13     // json格式
14     processdata: true,
15     // 非必须,默认 true
16     contenttype: "application/json;charsetset=utf-8",
17     //非必须,默认 application/x-www-form-urlencoded
18     success: function(data) {},
19     timeout: 1000,
20     // 超时时间,非必须,如果设置了,超时且存在error函数则会调用
21     error: function(xhr, statustext) {// 非必须
22     // statustext: "notmodified","timeout", 或者其他xmlhttprequest.statustext
23     }
24 });

 

注意事项


1. 如果 " $ " 符号不能使用,请用 " ajax " 替代,这个变量名若仍有冲突,请修改源代码首尾两行。

2. 如果返回的是json格式的字符串,会自动将字符串转为json对象传给success函数参数,其他情况均为字符串。

 

 

  第一次发博客,经验不足,引用了许多别人的代码,只是这功能已经缠了我很多天了,今天终于相对完善了,如有不妥,还请多多指教!