[轉帖]10 分鐘|全面圖解 AJAX
當前位置:點晴教程→知識管理交流
→『 技術文檔交流 』
:10 分鐘|全面圖解 AJAX
閱讀本文需要 30 分鐘,請先收藏轉發后再看。 先上原理圖:(另外這張圖是我在博客園畫的圖,所以水印是博客園的,也歡迎大家關注我的博客園。) 背景:1. 傳統的 Web 網站,提交表單,需要重新加載整個頁面。 2. 如果服務器長時間未能返回 Response,則客戶端將會無響應,用戶體驗很差。 3. 服務端返回 Response 后,瀏覽器需要加載整個頁面,對瀏覽器的負擔也是很大的。 4. 瀏覽器提交表單后,發送的數據量大,造成網絡的性能問題。 問題:1. 如何改進? 2.AJAX 是什么? 3. 有什么優勢? 4. 有什么缺點? 一、什么是 AJAX1. 為什么需要 AJAX當需要從服務器獲取數據,并刷新頁面的操作,如果不采用 AJAX,則需要用提交整個表單的方式,當提交表單時,發送請求給服務器,頁面需要等待服務器發送完 response 后,頁面才能恢復操作。 2.AJAX 的概念:1.AJAX = 異步 Javascript 和 XML。 2.AJAX 是一種用于創建快速動態網頁的技術。 3. 通過在后臺與服務器進行少量數據交換,可以使網頁實現異步更新。 4. 可以在不重新加載整個網頁的情況下,對網頁的某部分進行更新。 3. 什么叫異步當前頁面發送一個請求給服務器,當前頁面不需要等待服務器響應才能操作網頁。發送完請求之后,當前頁面可以繼續瀏覽,操作。 4. 什么叫局部刷新我們可以用兩種方式來實現部分刷新。 1. iframe 頁面重載的方式。 這種方式雖然實現了部分刷新,但是是頁面的重載,所以也會帶來性能上的問題。 Step1. 在頁面中定義一個 Iframe <iframe id="indexFrame" name="index" width="1000" height="800" frameborder="0" marginwidth="0" marginheight="0" scrolling="yes" style="margin-top:100px;"></iframe> Step2. 設置 Iframe 的 src var indexFrame = document.getElementById("indexFrame");indexFrame.src = "introduction.php"; Step3. 添加一個 button 的點擊事件,當點擊這個 button 時,重新設置 Iframe 的 src,實現 iframe 里面的頁面刷新。Iframe 外面的內容不刷新。 <button id="room" onclick='IndexClick("room")'>Click Me!</button> function IndexClick(moduleKey) { var indexFrame = document.getElementById("indexFrame"); if(indexFrame == null) { indexFrame = parent.document.getElementById("indexFrame"); } var url = "introduction.php"; switch (moduleKey) { case "introduction": url = "introduction.php"; break; case "room": url = "room.php"; break; default: { } } indexFrame.src = url;} 通過這種方式我們可以實現一個導航欄的功能: 2.AJAX 方式 Step1.JavaScrpit 發送異步請求 Step2. 服務端查詢數據庫,返回數據 Step3. 服務端返回 Response Step4. 客戶端根據返回的 Response,來用 Javascript 操作 DOM。 看下面的例子: 當我們切換 dropDownList 中的 Item 時,Javascript 發送異步請求給 Server 端,Server 端返回數據,然后 Javascript 將數據解析出來,拼接了一個 Table,將 Table 呈現在頁面上。 二、提交 Form 表單的原理1. 代碼 客戶端代碼: <form id="form1" action="Test.ashx" method="get"> 您的姓名1:<input type="text" name="fname" size="20" /> <input type="submit" name="submit" value="Sumbit"> </form> 服務端代碼: public void ProcessRequest (HttpContext context){ //Delay for (int i = 0; i < 2; i++) { System.Threading.Thread.Sleep(1000); } //從Requset.Form中獲取fname的值。使用Form獲取請求的鍵值對的值的前提條件是HTTP request Content-Type 值必須是"application/x-www-form-urlencoded" 或 "multipart/form-data". string fname = context.Request["fname"]; context.Response.ContentType = "text/plain"; //將字符串寫入 HTTP 響應輸出流。 context.Response.Write("Hello World " + fname); } 2. 將代碼部署到 IIS3. 打開站點:http://localhost:8003/Test.html
4. 輸入 “Jackson0714” 然后點擊 Sumbit 按鈕頁面會重新刷新,顯示 "Hello World Jackson0714" 5. 提交 Form 表單后,頁面發送請求和服務端返回響應的流程
6. 通過抓包,我們可以得到 HTTP Headers瀏覽器發送 HTTP 給服務端,采取的協議是 HTTP 協議。 在傳輸過程中,我們可以看下 HTTP Headers。 三、AJAX 提交請求和服務響應的原理1. 代碼客戶端 HTML 代碼: <!DOCTYPE html> <html lang="en" xmlns="http://www.w3.org/1999/xhtml"><head> <meta charset="utf-8" /> <title></title> <script type="text/javascript" src="Ajax.js"></script> </head><body> <div id="Test" style="background-color:#40eeee"> 您的姓名2:<input type="text" id="testGetName" size="20" /> <button type="button" onclick="testGet();">Ajax Get請求</button> </div> <div id="Test" style="background-color:#ff6a00"> 您的姓名3:<input type="text" id="testPostName" size="20" /> <button type="button" onclick="testPost();">Ajax Post請求</button> </div> <div id="myDiv" /> </body></html> 客戶端 JS 代碼: var xmlhttp = createRequest(); function testGet() { var fname = document.getElementById("testGetName").value; xmlhttp.open("GET", "Test.ashx?fname=" + fname + "&random=" + Math.random() , true); xmlhttp.onreadystatechange = callback; xmlhttp.send(null);} function testPost() { var fname = document.getElementById("testPostName").value; xmlhttp.open("POST", "Test.ashx?" + "&random=" + Math.random() , true); xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8"); xmlhttp.onreadystatechange = callback; xmlhttp.send("fname="+fname); } function createRequest() { var xmlhttp; if (window.XMLHttpRequest) { // code for IE7+, Firefox, Chrome, Opera, Safari xmlhttp = new XMLHttpRequest(); } else { // code for IE6, IE5 xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); } return xmlhttp} function callback() { if (xmlhttp.readyState == 4 && xmlhttp.status == 200) { document.getElementById("myDiv").innerHTML = xmlhttp.responseText; }} 這里有一點需要注意
1. 讓服務端能夠操作這個變量,如果定義成局部變量,則服務端返回 response 時,不能對 xmlhttp 的屬性賦值。回調函數要求 request 是全局的,才能訪問這個變量和它的屬性值。 2. 定義成全局變量后,可能出現兩個請求或多個請求共享同一個請求對象。而這個請求對象只能存放一個回調函數來處理服務器響應。當服務器返回兩個請求的 Response 后,可能會調用后指定的回調函數。所以可能有兩個完全不同的服務器響應由同一個回調函數處理,而這可能并不是正確的處理。解決辦法是創建兩個不同的請求對象。 服務端代碼不變。 2. 輸入 “Jackson0714” 然后點擊 Sumbit 按鈕頁面不會刷新,在最下面顯示 "Hello World Jackson0714" 3.AJAX 發送請求和服務端返回響應的流程
4. 通過抓包,我們可以得到 HTTP Headers瀏覽器發送 HTTP 給服務端,采取的協議是 HTTP 協議。 在傳輸過程中,我們可以看下 HTTP Headers:
5.AJAX GET 和 POST 方式區別AJAX 發送請求和 POST 發送請求的代碼如下: //GET方式function testGet() { var fname = document.getElementById("testGetName").value; xmlhttp.open("GET", "Test.ashx?fname=" + fname + "&random=" + Math.random() , true);xmlhttp.onreadystatechange = callback; xmlhttp.send(null);} //POST方式function testPost() { var fname = document.getElementById("testPostName").value; xmlhttp.open("POST", "Test.ashx?" + "&random=" + Math.random() , true); xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8"); xmlhttp.onreadystatechange = callback; xmlhttp.send("fname="+fname); }
1. 請求的 URL 中,POST 方式可以添加鍵值對,也可以不添加 2.GET 方式中,send 方法傳遞值無效。對于 IE 瀏覽器可以忽略 send () 方法的參數。但是對于 FireFox,必須提供一個 null 引用,否則回調行為將不規律。這是在編寫客戶端腳本時你會發現的一個跨瀏覽器兼容的問題。 3.POST 可以用 send 方法發送額外信息。發送的信息存放在 content 中 4.Post 方式需要指定 Request Header 的類型。Get 方式不需要指定。 5.GET 方式將參數暴露在 URL 中,POST 不暴露。
四、XMLHttpRequest 對象的知識1.XMLHttpRequest 對象的方法2.XMLHttpRequest 對象的屬性
五、JQuery 實現 AJAX下面的代碼實現了當切換 dropDownList 的 item 時,觸發 getWeeklyCalendar 方法,用 JQuery 的類庫方法 $.ajax 來發送 AJAX 請求。 客戶端 JQuery 代碼 function getWeeklyCalendar(name,currentDate,mode){ $.ajax({ type:'POST', url:'weekProcess.php',data:'func=getWeeklyCalender&name='+name+'¤tDate='+currentDate+'& mode='+mode, success:function(data){ paintWeeklyCandler(data); } });} 后臺成功返回 Response 后,執行 paintWeeklyCandler (data) 方法 后臺 PHP 代碼 <?php<br> //定義返回的Response的格式為JSON格式 header('Content-type: text/json');<br> //引入自定義的數據庫連接文件 include 'dbConfig.php';<br> //引入自定義的設置session的文件 include_once 'session.php'; /* * Function requested by Ajax */ if(isset($_POST['func']) && !empty($_POST['func'])) { switch($_POST['func']){ case 'getWeeklyCalender': getWeeklyCalender($_POST['name'],$_POST['currentDate'],$_POST['mode']); break; case 'getWeeklyStatus': getWeeklyStatus($_POST['name'],$_POST['currentDate'],$_POST['mode']); break; case 'getEvents': getEvents($_POST['date'],$_POST['name']); break; default: break; }} function getWeeklyCalender($name = '',$currentDate = '',$mode = ''){ //邏輯代碼<br> <br> <br> //返回JSON格式的Response echo json_encode(array('result'=>$DaysOfWeekResultsArray)); }<br>?> 六、優勢1. 使用異步方式與服務器通信,頁面不需要重新加載,頁面無刷新 2. 按需取數據,減少服務器的負擔 3. 使得 Web 應用程序更為迅捷地響應用戶交互 4.AJAX 基于標準化的并被廣泛支持的技術,不需要下載瀏覽器插件或者小程序,但需要客戶允許 Javascript 在瀏覽器上執行 5. 瀏覽器的內容和服務端代碼進行分離。頁面的內容全部由 JAVAscript 來控制,服務端負責邏輯的校驗和從數據庫中拿數據。
七、缺點1. 安全問題:將服務端的方法暴露出來,黑客可利用這一點進行攻擊 2. 大量 JS 代碼,容易出錯 3.Ajax 的無刷新重載,由于頁面的變化沒有刷新重載那么明顯,所以容易給用戶帶來困擾 —— 用戶不太清楚現在的數據是新的還是已經更新過的;現有的解決有:在相關位置提示、數據更新的區域設計得比較明顯、數據更新后給用戶提示等 4. 可能破壞瀏覽器后退按鈕的正常行為; 5. 一些手持設備(如手機、PAD 等)自帶的瀏覽器現在還不能很好的支持 Ajax
八、應用場景1. 對數據進行過濾和操縱相關數據的場景 2. 添加 / 刪除樹節點 3. 添加 / 刪除列表中的某一行記錄 4. 切換下拉列表 item 5. 注冊用戶名重名的校驗
九、不適用場景1. 整個頁面內容的保存 2. 導航 該文章在 2023/10/28 16:23:57 編輯過 |
關鍵字查詢
相關文章
正在查詢... |