模仿JQuery封装ajax功能
需求分析
因为有时候想提高性能,只需要一个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);
View Code
用法
高度模仿JQ。
1 // get请求 2 $.get("", {}, function(data) {}) 3 4 // post请求 5 $.post("", {}, function(data) {}) 6 7 // 更完整的ajax 8 $.ajax({ 9 type: "post", // 非必须,默认 get 10 url: "", 11 data: {}, // json格式 12 processData: true, // 非必须,默认 true 13 contentType: "application/json;charsetset=UTF-8", //非必须,默认 application/x-www-form-urlencoded 14 success: function(data) { 15 }, 16 timeout:1000, // 超时时间,非必须,如果设置了,超时且存在error函数则会调用 17 error: function(xhr, statusText) { 18 // 非必须 19 // statusText: "notmodified","timeout", 或者其他xmlHttpRequest.statusText 20 }
View Code
注意事项
1. 如果 ” $ ” 符号不能使用,请用 ” Ajax ” 替代,这个变量名若仍有冲突,请修改源代码首尾两行。
2. 如果返回的是json格式的字符串,会自动将字符串转为json对象传给success函数参数,其他情况均为字符串。
第一次发博客,经验不足,引用了许多别人的代码,只是这功能已经缠了我很多天了,今天终于相对完善了,如有不妥,还请多多指教!