需求分析 因為有時候想提高性能,只需要一個ajax函數,不想引入較大的jq文件,嘗試過axios,可是get方法不支持多層嵌套的json,post方式後臺接收方式似乎要變。。也許是我不太會用吧。。其實換個方式接收也沒什麼,只是習慣了JQ序列化參數。所以上網搜集了很多資料,同時也進一步瞭解了一點JQ。 ...
需求分析
因為有時候想提高性能,只需要一個ajax函數,不想引入較大的jq文件,嘗試過axios,可是get方法不支持多層嵌套的json,post方式後臺接收方式似乎要變。。也許是我不太會用吧。。其實換個方式接收也沒什麼,只是習慣了JQ序列化參數。所以上網搜集了很多資料,同時也進一步瞭解了一點JQ。以下代碼很多來自於網上,自己整合了一下。
封裝代碼
1 /* 2 * @Description: 模仿jQuery封裝簡單的ajax功能。 3 * @Author: [email protected] 4 * @Date: 2019-06-25 15:19:30 5 * @LastEditTime: 2019-09-14 23:21:01 6 * @LastEditors: Please set LastEditors 7 */ 8 9 var Ajax = {}; 10 (function($) { 11 function ajax(options) { 12 var str; 13 var xmlHttpRequest; 14 var timer; 15 if (window.XMLHttpRequest) { 16 xmlHttpRequest = new XMLHttpRequest(); 17 } else { 18 xmlHttpRequest = new ActiveXObject("Microsoft.XMLHTTP"); 19 } 20 options = Object.assign( 21 {}, 22 { 23 type: "GET", 24 processData: true, 25 contentType: "application/x-www-form-urlencoded" 26 }, 27 options 28 ); 29 if (options.type.toUpperCase() !== "GET") { 30 xmlHttpRequest.open(options.type.toUpperCase(), options.url, true); 31 xmlHttpRequest.setRequestHeader("Content-type", options.contentType); 32 if (options.processData) { 33 str = param(options.data); 34 } else { 35 str = options.data; 36 } 37 xmlHttpRequest.send(str); 38 } else { 39 str = param(Object.assign(urlorQuerytoObject(options.url), options.data)); 40 if (options.url.indexOf("?") !== -1) { 41 options.url = options.url.substr(0, options.url.indexOf("?")); 42 } 43 xmlHttpRequest.open("GET", options.url + "?" + str, true); 44 xmlHttpRequest.send(null); 45 } 46 xmlHttpRequest.onreadystatechange = function() { 47 var textStatus = ""; 48 if (xmlHttpRequest.readyState === 4) { 49 clearInterval(timer); 50 if ((xmlHttpRequest.status >= 200 && xmlHttpRequest.status < 300) || xmlHttpRequest.status === 304) { 51 if (xmlHttpRequest.status === 304) { 52 textStatus = "notmodified"; 53 } else { 54 textStatus = "success"; 55 } 56 try { 57 // 如果是JSON格式,自動轉換為JSON對象 58 options.success(JSON.parse(xmlHttpRequest.responseText), textStatus); 59 } catch (e) { 60 options.success(xmlHttpRequest.responseText, textStatus); 61 } 62 } else { 63 textStatus = "error"; 64 if (typeof options.error === "function") { 65 options.error(xmlHttpRequest, textStatus); 66 } 67 } 68 if (typeof options.complete === "function") { 69 options.complete(xmlHttpRequest, textStatus); 70 } 71 } 72 }; 73 //判斷是否超時 74 if (typeof options.timeout === "number") { 75 timer = setTimeout(function() { 76 if (typeof options.error === "function") { 77 options.error(xmlHttpRequest, "timeout"); 78 options.complete(xmlHttpRequest, "timeout"); 79 } 80 if (typeof options.complete === "function") { 81 options.complete(xmlHttpRequest, "timeout"); 82 } 83 xmlHttpRequest.abort(); 84 }, options.timeout); 85 } 86 } 87 88 // 把url中的查詢字元串轉為對象,主要是想當方式為get時,用data對象的參數覆蓋掉url中的參數 89 function urlorQuerytoObject(urlorQuery) { 90 var queryArr = []; 91 var urlSplit = urlorQuery.split("?"); 92 queryArr[0] = urlSplit[0]; 93 if (urlSplit[1]) { 94 queryArr[0] = urlSplit[1]; 95 } 96 queryArr = queryArr[0].split("&"); 97 var obj = {}; 98 var i = 0; 99 var temp; 100 var key; 101 var value; 102 for (i = 0; i < queryArr.length; i += 1) { 103 temp = queryArr[i].split("="); 104 key = temp[0]; 105 value = temp[1]; 106 obj[key] = value; 107 } 108 return obj; 109 } 110 111 // 序列化參數 112 // 轉載自 https://www.jianshu.com/p/0ca22d53feea 113 function param(obj, traditional) { 114 if (traditional === "undefined") { 115 traditional = false; 116 } 117 var rbracket = /\[\]$/, 118 op = Object.prototype, 119 ap = Array.prototype, 120 aeach = ap.forEach, 121 ostring = op.toString; 122 123 function isFunction(it) { 124 return ostring.call(it) === "[object Function]"; 125 } 126 127 function isArray(it) { 128 return ostring.call(it) === "[object Array]"; 129 } 130 131 function isObject(it) { 132 return ostring.call(it) === "[object Object]"; 133 } 134 135 function buildParams(prefix, obj, traditional, add) { 136 var name; 137 if (isArray(obj)) { 138 // Serialize array item. 139 aeach.call(obj, function(v, i) { 140 if (traditional || rbracket.test(prefix)) { 141 // Treat each array item as a scalar. 142 add(prefix, v); 143 } else { 144 // Item is non-scalar (array or object), encode its numeric index. 145 buildParams( 146 prefix + "[" + (typeof v === "object" && v != null ? i : "") + "]", 147 v, 148 traditional, 149 add 150 ); 151 } 152 }); 153 } else if (!traditional && isObject(obj)) { 154 // Serialize object item. 155 for (name in obj) { 156 buildParams(prefix + "[" + name + "]", obj[name], traditional, add); 157 } 158 } else { 159 // Serialize scalar item. 160 add(prefix, obj); 161 } 162 } 163 // Serialize an array of form elements or a set of 164 // key/values into a query string 165 function jollyparam(a, traditional) { 166 var prefix, 167 s = [], 168 add = function(key, valueOrFunction) { 169 // If value is a function, invoke it and use its return value 170 var value = isFunction(valueOrFunction) ? valueOrFunction() : valueOrFunction; 171 s[s.length] = encodeURIComponent(key) + "=" + encodeURIComponent(value == null ? "" : value); 172 }; 173 // If an array was passed in, assume that it is an array of form elements. 174 if (isArray(a)) { 175 // Serialize the form elements 176 aeach.call(a, function(item) { 177 add(item.name, item.value); 178 }); 179 } else { 180 // If traditional, encode the "old" way (the way 1.3.2 or older 181 // did it), otherwise encode params recursively. 182 for (prefix in a) { 183 buildParams(prefix, a[prefix], traditional, add); 184 } 185 } 186 // Return the resulting serialization 187 return s.join("&"); 188 } 189 return jollyparam(obj, traditional); 190 } 191 192 // 為避免 Object.assign 不能使用 193 // 轉載自 https://my.oschina.net/u/3828418/blog/2056310 194 if (typeof Object.assign != "function") { 195 Object.assign = function(target) { 196 "use strict"; 197 if (target == null) { 198 throw new TypeError("Cannot convert undefined or null to object"); 199 } 200 target = Object(target); 201 for (var index = 1; index < arguments.length; index++) { 202 var source = arguments[index]; 203 if (source != null) { 204 for (var key in source) { 205 if (Object.prototype.hasOwnProperty.call(source, key)) { 206 target[key] = source[key]; 207 } 208 } 209 } 210 } 211 return target; 212 }; 213 } 214 215 $ = { 216 get: function(url, data, success) { 217 return ajax({ url: url, data: data, success: success }); 218 }, 219 post: function(url, data, success) { 220 return ajax({ 221 type: "POST", 222 url: url, 223 data: data, 224 success: success 225 }); 226 }, 227 ajax: function(options) { 228 return ajax(options); 229 }, 230 param: function(obj, traditional) { 231 return param(obj, traditional); 232 }, 233 urlorQuerytoObject: function(urlorQuery) { 234 return urlorQuerytoObject(urlorQuery); 235 } 236 }; 237 238 // 滿足 JQuery 的使用習慣 239 if (typeof window.$ === "undefined") { 240 window.$ = $; 241 } 242 })(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: { }, 12 processData: true, // 非必須,預設 true 13 contentType: "application/x-www-form-urlencoded", // 非必須,預設 application/x-www-form-urlencoded 14 success: function(responseData, textStatus) { 15 // textStatus : "success"、"notmodified" 16 }, 17 // timeout: 1, // 非必須,超時毫秒數,如果設置了,超時且存在error函數則會調用 18 error: function(xhr, textStatus) { 19 // 非必須 20 // textStatus: "error"、"timeout" 21 }, 22 complete: function(xhr, textStatus) { 23 // 非必須,無論成敗最後均調用 24 // textStatus: "success"、"notmodified"、"error"、"timeout" 25 } 26 });View Code
註意事項
1. 如果 " $ " 符號不能使用,請用 " Ajax " 替代,這個變數名若仍有衝突,請修改源代碼首尾兩行。
2. 如果返回的是json格式的字元串,會自動將字元串轉為json對象傳給success函數參數,其他情況均為字元串。
第一次發博客,經驗不足,引用了許多別人的代碼,只是這功能已經纏了我很多天了,今天終於相對完善了,如有不妥,還請多多指教!