模仿JQuery封裝ajax功能

来源:https://www.cnblogs.com/kill370354/archive/2019/09/10/11497480.html
-Advertisement-
Play Games

需求分析 因為有時候想提高性能,只需要一個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函數參數,其他情況均為字元串。

 

 

  第一次發博客,經驗不足,引用了許多別人的代碼,只是這功能已經纏了我很多天了,今天終於相對完善了,如有不妥,還請多多指教!

 github


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • https://blog.csdn.net/zhouzuoluo/article/details/81010331 ...
  • 表單簡介 Form表單主要用於用戶與Web應用程式進行數據的交互,它允許用戶將數據發給web應用程式,網頁也可以攔截數據的發送以便自己使用。form通常由一到多個表單元素組成,這些表單元素是單行/多行文本框,下拉菜單,按鈕,覆選框,單選按鈕,時間表單元素時 一般要配合label標簽,用於描述其目的。 ...
  • 通過瀏覽器向web服務傳遞base64碼的圖片時遇到參數過長的問題? 解決辦法:查看aiohttp的源碼:aiohttp/http_parser.py下找到: class HeadersParser: def __init__(self, max_line_size: int=8190, max_h ...
  • 彈性佈局的名稱概念: 1、容器:需要添加彈性佈局的父元素;項目:彈性佈局容器中的每一個子元素,稱為項目。 2、主軸:在彈性佈局中,我們會通過屬性規定水平/垂直方向(flex-direction)為主軸;與主軸垂直的另一方向,稱為交叉軸。 彈性佈局的重要的幾大基礎屬性: 1、flex-directio ...
  • 不藉助Math函數求開根值 1、二分迭代法求n開根後的值 思路: left=0 right=n mid=(left+right)/2 比較mid^2與n大小 =輸出; >改變範圍,right=mid,mid重新計算; <改變範圍,left=mid,mid重新計算; 如此迴圈,不過只能是逼近,並不能完 ...
  • 問題產生在學習cabvas給畫布畫圖像的時候發現使用IE edge瀏覽器可以正常顯示圖像,而chrome則不行,經百度後知道是因為chrome瀏覽器會先載入javascript代碼,之後才載入圖片,這樣就造成了我是用drawImage的時候那個圖片並沒有載入出來。解決辦法把畫圖片到canvas的代碼 ...
  • 什麼是HTML? HTML是HyperText Markup Language(超文本標記語言)的簡寫,他不是一種編程語言,而是一種標記語言,用於告訴瀏覽器如何構造你的頁面。“超文本”就是指頁面可以包含圖片、鏈接,甚至音樂、程式等非文字元素。HTML也是一種規範,一種標準,它通過標記符號來 標記要顯 ...
  • 互聯網的迅速發展,軟體行業成了更多年輕人的就業選擇。HTML5簡單易學門檻低,是Web時代前端開發超好用的工具。而HTML5開發人員的就業薪資也遠遠高於其他行業。 資料顯示,初級HTML5開發人員的平均薪資在8K-10K左右,擁有一定工作經驗的人薪資普遍達到15K-20K。如此廣闊的前景當然吸引了無 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...