圖文解析AJAX的原理
先上原理圖:
背景:
1.傳統(tǒng)的Web網(wǎng)站,提交表單,需要重新加載整個頁面。
2.如果服務(wù)器長時間未能返回Response,則客戶端將會無響應(yīng),用戶體驗(yàn)很差。
3.服務(wù)端返回Response后,瀏覽器需要加載整個頁面,對瀏覽器的負(fù)擔(dān)也是很大的。
4.瀏覽器提交表單后,發(fā)送的數(shù)據(jù)量大,造成網(wǎng)絡(luò)的性能問題。
問題:
1.如何改進(jìn)?
2.AJAX是什么?
3.有什么優(yōu)勢?
4.有什么缺點(diǎn)?
一、什么是 AJAX
1.為什么需要AJAX
當(dāng)需要從服務(wù)器獲取數(shù)據(jù),并刷新頁面的操作,如果不采用AJAX,則需要用提交整個表單的方式,當(dāng)提交表單時,發(fā)送請求給服務(wù)器,頁面需要等待服務(wù)器發(fā)送完response后,頁面才能恢復(fù)操作。
2.AJAX的概念:
1.AJAX = 異步 JavaScript 和 XML。
2.AJAX 是一種用于創(chuàng)建快速動態(tài)網(wǎng)頁的技術(shù)。
3.通過在后臺與服務(wù)器進(jìn)行少量數(shù)據(jù)交換,可以使網(wǎng)頁實(shí)現(xiàn)異步更新。
4.可以在不重新加載整個網(wǎng)頁的情況下,對網(wǎng)頁的某部分進(jìn)行更新。
3.什么叫異步
當(dāng)前頁面發(fā)送一個請求給服務(wù)器,當(dāng)前頁面不需要等待服務(wù)器響應(yīng)才能操作網(wǎng)頁。發(fā)送完請求之后,當(dāng)前頁面可以繼續(xù)瀏覽,操作。
4.什么叫局部刷新
我們可以用兩種方式來實(shí)現(xiàn)部分刷新。
1. iframe頁面重載的方式。
這種方式雖然實(shí)現(xiàn)了部分刷新,但是是頁面的重載,所以也會帶來性能上的問題。
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.設(shè)置Iframe的src
var indexFrame = document.getElementById("indexFrame"); indexFrame.src = "introduction.php";
Step3.添加一個button的點(diǎn)擊事件,當(dāng)點(diǎn)擊這個button時,重新設(shè)置Iframe的src,實(shí)現(xiàn)iframe里面的頁面刷新。Iframe外面的內(nèi)容不刷新。
<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; }
通過這種方式我們可以實(shí)現(xiàn)一個導(dǎo)航欄的功能:
2.AJAX方式
Step1.JavaScrpit發(fā)送異步請求
Step2.服務(wù)端查詢數(shù)據(jù)庫,返回數(shù)據(jù)
Step3.服務(wù)端返回Response
Step4.客戶端根據(jù)返回的Response,來用JavaScript操作DOM。
看下面的例子:
當(dāng)我們切換DropDownList中的Item時,JavaScript發(fā)送異步請求給Server端,Server端返回數(shù)據(jù),然后JavaScript將數(shù)據(jù)解析出來,拼接了一個Table,將Table呈現(xiàn)在頁面上。
二、提交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>
服務(wù)端代碼:
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 響應(yīng)輸出流。 context.Response.Write("Hello World " + fname); }
2.將代碼部署到IIS
3.打開站點(diǎn):
http://localhost:8003/Test.html
4.輸入“Jackson0714”然后點(diǎn)擊Sumbit按鈕,頁面會重新刷新,顯示"Hello World Jackson0714"
5.提交Form表單后,頁面發(fā)送請求和服務(wù)端返回響應(yīng)的流程
6.通過抓包,我們可以得到HTTP Headers
瀏覽器發(fā)送HTTP給服務(wù)端,采取的協(xié)議是HTTP協(xié)議。
在傳輸過程中,我們可以看下HTTP Headers。
三、AJAX提交請求和服務(wù)響應(yīng)的原理
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; } }
這里有一點(diǎn)需要注意
var xmlhttp = createRequest(); 。
1.讓服務(wù)端能夠操作這個變量,如果定義成局部變量,則服務(wù)端返回response時,不能對xmlhttp的屬性賦值?;卣{(diào)函數(shù)要求request是全局的,才能訪問這個變量和它的屬性值。
2.定義成全局變量后,可能出現(xiàn)兩個請求或多個請求共享同一個請求對象。而這個請求對象只能存放一個回調(diào)函數(shù)來處理服務(wù)器響應(yīng)。當(dāng)服務(wù)器返回兩個請求的Response后,可能會調(diào)用后指定的回調(diào)函數(shù)。所以可能有兩個完全不同的服務(wù)器響應(yīng)由同一個回調(diào)函數(shù)處理,而這可能并不是正確的處理。解決辦法是創(chuàng)建兩個不同的請求對象。
服務(wù)端代碼不變。
2.輸入“Jackson0714”然后點(diǎn)擊Sumbit按鈕,頁面不會刷新,在最下面顯示"Hello World Jackson0714"
3.AJAX發(fā)送請求和服務(wù)端返回響應(yīng)的流程
4.通過抓包,我們可以得到HTTP Headers
瀏覽器發(fā)送HTTP給服務(wù)端,采取的協(xié)議是HTTP協(xié)議。
在傳輸過程中,我們可以看下HTTP Headers:
5.AJAX GET和POST方式區(qū)別
AJAX發(fā)送請求和POST發(fā)送請求的代碼如下:
//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); }
四、XMLHttpRequest 對象的知識
1.XMLHttpRequest 對象的方法
2.XMLHttpRequest 對象的屬性
五、JQuery實(shí)現(xiàn)AJAX
下面的代碼實(shí)現(xiàn)了當(dāng)切換DropDownList的item時,觸發(fā)getWeeklyCalendar方法,用JQuery的類庫方法$.ajax來發(fā)送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后,執(zhí)行paintWeeklyCandler(data)方法
后臺PHP代碼
<?php<br> //定義返回的Response的格式為JSON格式 header('Content-type: text/json');<br> //引入自定義的數(shù)據(jù)庫連接文件 include 'dbConfig.php';<br> //引入自定義的設(shè)置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>?>
六、優(yōu)勢
1.使用異步方式與服務(wù)器通信,頁面不需要重新加載,頁面無刷新
2.按需取數(shù)據(jù),減少服務(wù)器的負(fù)擔(dān)
3.使得Web應(yīng)用程序更為迅捷地響應(yīng)用戶交互
4.AJAX基于標(biāo)準(zhǔn)化的并被廣泛支持的技術(shù),不需要下載瀏覽器插件或者小程序,但需要客戶允許JavaScript在瀏覽器上執(zhí)行
5.瀏覽器的內(nèi)容和服務(wù)端代碼進(jìn)行分離。頁面的內(nèi)容全部由JAVAScript來控制,服務(wù)端負(fù)責(zé)邏輯的校驗(yàn)和從數(shù)據(jù)庫中拿數(shù)據(jù)。
七、缺點(diǎn)
1.安全問題:將服務(wù)端的方法暴露出來,黑客可利用這一點(diǎn)進(jìn)行攻擊
2.大量JS代碼,容易出錯
3.Ajax的無刷新重載,由于頁面的變化沒有刷新重載那么明顯,所以容易給用戶帶來困擾——用戶不太清楚現(xiàn)在的數(shù)據(jù)是新的還是已經(jīng)更新過的;現(xiàn)有的解決有:在相關(guān)位置提示、數(shù)據(jù)更新的區(qū)域設(shè)計得比較明顯、數(shù)據(jù)更新后給用戶提示等
4.可能破壞瀏覽器后退按鈕的正常行為;
5.一些手持設(shè)備(如手機(jī)、PAD等)自帶的瀏覽器現(xiàn)在還不能很好的支持Ajax
八、應(yīng)用場景
1.對數(shù)據(jù)進(jìn)行過濾和操縱相關(guān)數(shù)據(jù)的場景
2.添加/刪除樹節(jié)點(diǎn)
3.添加/刪除列表中的某一行記錄
4.切換下拉列表item
5.注冊用戶名重名的校驗(yàn)
九、不適用場景
1.整個頁面內(nèi)容的保存
2.導(dǎo)航
十、總結(jié)
以上就是本文的全部內(nèi)容,文章寫的很詳細(xì),希望對大家學(xué)習(xí)ajax能有所幫助哦。
相關(guān)文章
關(guān)于ajax對象一些常用屬性、事件和方法大小寫比較常見的問題總結(jié)
最近比較空閑,于是抽個時間整理些關(guān)于ajax方法的東東。在項(xiàng)目中經(jīng)常發(fā)現(xiàn)ajax板塊好多問題都是屬性,方法,事件大小寫不區(qū)分問題,最終導(dǎo)致了程序運(yùn)行出現(xiàn)麻煩,下面給大家介紹關(guān)于ajax對象一些常用屬性、事件和方法大小寫比較常見的問題總結(jié)2015-10-10Ajax工作原理及優(yōu)缺點(diǎn)實(shí)例解析
這篇文章主要介紹了Ajax工作原理及優(yōu)缺點(diǎn)實(shí)例解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-09-09將xml文件作為一個小的數(shù)據(jù)庫,進(jìn)行學(xué)生的增刪改查的簡單實(shí)例
下面小編就為大家?guī)硪黄獙ml文件作為一個小的數(shù)據(jù)庫,進(jìn)行學(xué)生的增刪改查的簡單實(shí)例。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-06-06Jquery中ajax提交表單幾種方法(get、post兩種方法)
ajax技術(shù)帶給我們的是良好的用戶體驗(yàn),同時,使用jquery可以簡化開發(fā),提高工作效率,接下來,腳本之家小編給大家分享Jquery中ajax提交表單幾種方法,需要的朋友可以參考下2015-09-09Ajax實(shí)現(xiàn)城市二級聯(lián)動(二)
這篇文章主要為大家詳細(xì)介紹了Ajax實(shí)現(xiàn)城市二級聯(lián)動的相關(guān)資料,將省份用ajax請求并渲染,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-02-02Ajax異步提交數(shù)據(jù)返回值的換行問題實(shí)例分析
這篇文章主要介紹了Ajax異步提交數(shù)據(jù)返回值的換行問題,結(jié)合實(shí)例形式較為詳細(xì)的分析了ajax異步提交過程中返回值帶有換行的處理技巧,具有一定參考借鑒價值,需要的朋友可以參考下2015-12-12Ajax實(shí)現(xiàn)城市二級聯(lián)動(三)
這篇文章主要為大家詳細(xì)介紹了Ajax實(shí)現(xiàn)城市二級聯(lián)動的方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-02-02Servlet 與 Ajax 交互一直報status=parsererror的解決辦法
這篇文章主要介紹了Servlet 與 Ajax 交互一直報status=parsererror的解決辦法,非常不錯,具有參考借鑒價值,需要的朋友可以參考下2017-03-03