這次帶給大家詳解Ajax的原理及優缺點有哪些,使用Ajax的原理及優缺點的注意事項有哪些,下面就是實戰案例,一起來看一下。
1、ajax技術的背景
#不可否認,ajax技術的流行得益於google的大力推廣,正是由於google earth 、google suggest以及gmail等對ajax技術的廣泛應用,催生了ajax的流行。而這也讓微軟感到無比的尷尬,因為早在97年,微軟便已經發明了ajax中的關鍵技術,並且在99年IE5推出之時,它便開始支持XmlHttpRequest對象,並且微軟之前已經開始在它的一些產品中應用ajax,比如說MSDN網站選單中的一些應用。遺憾的是,不知道出於什麼想法,當時微軟發明了ajax的核心技術之後,並沒有看到它的潛力而加以發展和推廣,而是將它擱置起來。對這一點來說,我個人是覺得非常奇怪的,因為以微軟的資源和它的戰略眼光來說,應該不會看不到ajax技術的前景,唯一的解釋也許就是因為當時它的主要競爭對手Netscape的消失反而使它變得麻痺和遲鈍,畢竟巨人也有打盹的時候,例如IBM曾經在對微軟戰略上的失誤。正是這次的失誤,成就了它現在的競爭對手google在ajax方面的領先地位,而事實上google目前在ajax技術方面的領先是微軟所無法達到的,這一點在後面我講述ajax缺陷的時候也會提到。現在微軟也意識到了這個問題,因此它也開始在ajax領域奮起直追,比如說推出它自己的ajax框架atlas,並且在.NET2.0也提供了一個用來實現異步回調的接口,即ICallBack接口。那麼微軟為什麼對自己在ajax方面的落後如此緊張呢?現在就讓我們來分析一下ajax技術後面隱藏的深刻意義。
2、ajax技術的意義
我們在平時的開發中都多多少少的接觸或應用到了ajax,談到ajax科技的意義,我們關注得最多的毫無疑問是提升用戶的體驗。但是,如果我們結合未來電腦和網路的發展趨勢,我們會發現ajax技術在某些方面正好代表了這種趨勢。為什麼要這樣說呢?我們知道,自從電腦出現以來,一直是桌面軟體佔據著絕對主導的地位,但是互聯網的出現和成功使這一切開始發生著微妙的變化。相當一部分的人都相信,遲早有一天,數據和電腦軟體將會從桌面轉移到網路。也就是說,將來的電腦有可能拋棄笨重的硬碟,而直接從網路來獲取數據和服務,我記得我念大學的時候,有位教授給我們上課的時候,曾經設想過這樣一種情景,也許在將來的電腦桌面上,沒有任何多餘的軟體和程序,而僅僅只有一個IE,雖然現在看起來我們距離這一天還很遙遠,並且這其中還有很多的問題需要解決,但是我覺得這個並非夢想,而是遲早將實現的現實。那麼,這其中的主要問題就是互聯網的連接不穩定,誰也不願意看著自己的電腦從伺服器一點一滴的下載數據,那麼,ajax是不是解決了這個問題呢,說實話,與其說ajax解決了這個問題,倒不如它只是掩蓋了這個問題,它只是在伺服器和客戶端之間充當了一個緩衝器,讓用戶誤以為服務沒有中斷。精確的說,ajax並不能提高從伺服器端下載資料的速度,而只是使這個等待不那麼令人沮喪。但正是這一點就足以產生巨大的影響和震動,它實際上也對桌面軟體產生了巨大的衝擊。這一點我用一個例子來說明,我們可以比較一下Outlook Express和Gmail,前者是典型的桌面軟體,後者是ajax所實現的B/S模式,實際上後者目前已經在慢慢取代前者了, Gmail在收發郵件的時候已經和Outlook Express的功能幾乎沒有差別了,而且它不需要安裝客戶端程式。這就是為什麼微軟對ajax所帶來的衝擊有著如此的恐懼心理,並且在它前不久所進行的調查之中,將google看做他們未來十年內的主要競爭對手的主要原因之一。當然,這種變化也不會將桌面軟體全部淘汰,現有的瀏覽器還沒有一個能像PhotoShop等桌面程式那樣處理複雜的影像。但是我們也不能忽略它所帶來的影響和衝擊。
3、關於ajax的名字
ajax 的全名是Asynchronous JavaScript and XML,其中,Asynchronous 是異步的意思,它有別於傳統web開發中所採用的同步的方式。
關於同步和非同步
非同步傳輸是面向字元的傳輸,它的單位是字元;而同步傳輸是面向位元的傳輸,它的單位是楨,它傳輸的時候要求接受方和發送方的時鐘是保持一致的。
具體來說,非同步傳輸是將位元分成小組來進行傳送。一般每個小組是一個8位字符,在每個小組的頭部和尾部都有一個開始位和一個停止位,它在傳送過程中接收方和發送方的時鐘不要求一致,也就是說,發送方可以在任何時刻發送這些小組,而接收方並不知道它何時到達。一個最明顯的例子就是電腦鍵盤和主機的通信,按下一個鍵的同時向主機發送一個8位元的ASCII代碼,鍵盤可以在任何時刻發送代碼,這取決於用戶的輸入速度,內部的硬體必須能夠在任何時刻接收一個鍵入的字元。這是一個典型的非同步傳輸過程。非同步傳輸存在一個潛在的問題,即接收方並不知道資料會在什麼時候到達。在它檢測到數據並做出回應之前,第一個比特已經過去了。這就像有人出乎意料地從後面走上來跟你說話,而你沒來得及反應過來,漏掉了最前面的幾個字。因此,每次非同步傳輸的訊息都以起始位元開頭,它通知接收方資料已經到達了,這就給了接收方回應、接收和快取資料位元的時間;在傳輸結束時,一個停止位表示該次傳輸訊息的終止。依照慣例,空閒(沒有傳送資料)的線路實際攜帶著一個代表二進位1的訊號。步傳輸的開始位元使訊號變成0,其他的位元使訊號隨傳輸的資料資訊而變化。最後,停止位元使訊號重新變回1,該訊號一直保持到下一個開始位元到達。例如在鍵盤上數字“1”,按照8位元的擴展ASCII編碼,將發送“00110001”,同時需要在8位元的前面加一個起始位,後面一個停止位。
同步傳輸的位元分組則大得多。它不是獨立地發送每個字符,每個字符都有自己的開始位和停止位,而是把它們組合起來一起發送。我們將這些組合稱為資料幀,或簡稱為幀。
資料幀的第一部分包含一組同步字符,它是一個獨特的位元組合,類似於前面提到的起始位,用於通知接收方一個幀已經到達,但它同時還能確保接收方的取樣速度和位元的到達速度保持一致,使收發雙方進入同步。
幀的最後一部分是一個幀結束標記。與同步字元一樣,它也是一個獨特的位元串,類似於前面提到的停止位,用於表示在下一幀開始之前沒有別的即將到達的資料了。
同步傳輸通常要比非同步傳輸快速得多。接收方不必對每個字元進行開始和停止的操作。一旦檢測到幀同步字符,它就在接下來的資料到達時接收它們。另外,同步傳輸的開銷也比較少。例如,一個典型的幀可能有500位元組(即4000位元)的數據,其中可能只包含100位元的開銷。這時,增加的位元組使傳輸的位元總數增加2.5%,這與非同步傳輸中25 %的增值要小得多。隨著資料幀中實際資料位元的增加,開銷位元所佔的百分比將會相應地減少。但是,資料位元越長,快取資料所需的緩衝區也越大,這就限制了一個幀的大小。另外,幀越大,它佔據傳輸媒體的連續時間也越長。在極端的情況下,這將導致其他用戶等太久。
小時,在這10小時內水沒有完全斷,只是流量比原來小了很多,在10個小時後恢復正常流量,那麼,如果是你會選擇哪種方式呢?顯然是後者。
4、ajax所包含的技術
#大家都知道ajax並非一種新的技術,而是幾種原有技術的結合體。它是由下列技術組合而成。
1.使用CSS和XHTML來表示。
2. 使用DOM模型來互動和動態顯示。
3.使用XMLHttpRequest來和伺服器進行非同步通訊。
4.使用javascript來綁定和呼叫。
在上面幾中技術中,除了XmlHttpRequest物件以外,其它所有的技術都是基於web標準並且已經得到了廣泛使用的,XMLHttpRequest雖然目前還沒有被W3C所採納,但是它已經是一個事實的標準,因為目前幾乎所有的主流瀏覽器都支援它。
5、ajax原理和XmlHttpRequest物件
Ajax的原理簡單來說透過XmlHttpRequest物件來向伺服器發異步請求,從伺服器獲得數據,然後用javascript來操作DOM而更新頁面。這其中最關鍵的一步就是從伺服器取得請求資料。要清楚這個過程和原理,我們必須對 XMLHttpRequest有所了解。
XMLHttpRequest是ajax的核心機制,它是在IE5中首先引入的,是一種支援非同步請求的技術。簡單的說,也就是javascript可以及時向伺服器提出請求和處理回應,而不阻塞使用者。達到無刷新的效果。
所以我們先從XMLHttpRequest講起,來看看它的運作原理。
首先,我們先來看看XMLHttpRequest這個物件的屬性。
它的屬性有:
onreadystatechange 每次狀態改變所觸發事件的事件處理程式。
responseText從伺服器程序傳回資料的字串形式。
responseXML從伺服器程序傳回的DOM相容的文件資料物件。
status從伺服器傳回的數字代碼,例如常見的404(未找到)和200(已就緒)
status Text伴隨狀態碼的字串資訊
readyState物件狀態值
0 (未初始化) 物件已建立,但是尚未初始化(尚未呼叫open方法)
1 (初始化) 物件已建立,尚未呼叫send方法
2 (發送資料) send方法已調用,但目前的狀態及http頭未知
3 (資料傳送中) 已接收部分數據,因為回應及http頭不全,這時透過responseBody和responseText取得部分資料會出現錯誤,
4 (完成) 資料接收完畢,此時可以透過透過responseXml和responseText取得完整的回應資料
但是,由於各瀏覽器之間存在差異,所以建立一個XMLHttpRequest物件可能需要不同的方法。這個差異主要體現在IE和其它瀏覽器之間。下面是一個比較標準的建立XMLHttpRequest物件的方法。
function CreateXmlHttp() { //非IE浏览器创建XmlHttpRequest对象 if(window.XmlHttpRequest) { xmlhttp=new XmlHttpRequest(); } //IE浏览器创建XmlHttpRequest对象 if(window.ActiveXObject) { try { xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); } catch(e) { try{ xmlhttp=new ActiveXObject("msxml2.XMLHTTP"); } catch(ex){} } } } function TestAjax() { var data=document.getElementByIdx("username").value; CreateXmlHttp(); if(!xmlhttp) { alert("创建xmlhttp对象异常!"); return false; } xmlhttp.open("POST",url,false); xmlhttp.onreadystatechange=function() { if(xmlhttp.readyState==4) { document.getElementByIdx("user1").innerHTML="数据正在加载..."; if(xmlhttp.status==200) { document.write(xmlhttp.responseText); } } } xmlhttp.send(); }
如上所示,函數首先檢查XMLHttpRequest的整體狀態並且保證它已經完成(readyStatus=4),也就是資料已經傳送完畢。然後根據伺服器的設定詢問請求狀態,如果一切已經就緒(status=200),那麼就執行下面需要的操作。
對於XmlHttpRequest的兩個方法,open和send,其中open方法指定了:
a、向伺服器提交資料的類型,即post還是get。
b、請求的url位址和傳遞的參數。
c、傳輸方式,false為同步,true為非同步。預設為true。如果是非同步通訊方式(true),客戶機就不等待伺服器的回應;如果是同步方式(false),客戶機就要等到伺服器回傳訊息後才去執行其他操作。我們需要根據實際需求來指定同步方式,在某些頁面中,可能會發出多個請求,甚至是有組織有計劃有隊形大規模的高強度的request,而後一個是會覆蓋前一個的,這個時候當然要指定同步方式。
Send方法用來傳送請求。
知道了XMLHttpRequest的工作流程,我們可以看出,XMLHttpRequest是完全用來向伺服器發出一個請求的,它的作用也局限於此,但它的作用是整個ajax實現的關鍵,因為ajax無非是兩個過程,發出請求和回應請求。並且它完全是一種客戶端的技術。而XMLHttpRequest正是處理了伺服器端和客戶端通訊的問題所以才會如此的重要。
現在,我們對ajax的原理大概可以有個了解了。我們可以把伺服器端看成一個資料接口,它回傳的是一個純文字流,當然,這個文字流可以是XML格式,可以是Html,可以是Javascript程式碼,也可以只是一個字串。這時候,XMLHttpRequest向伺服器端請求這個頁面,伺服器端將文字的結果寫入頁面,這和普通的web開發流程是一樣的,不同的是,客戶端在非同步取得這個結果後,不是直接顯示在頁面,而是先由javascript來處理,然後再顯示在頁面。至於現在流行的許多ajax控件,例如magicajax等,可以返回DataSet等其它資料類型,只是將這個過程封裝了的結果,本質上他們並沒有什麼太大的區別。
6、ajax的優點
Ajax的帶給我們的好處大家基本上都深有體會,在這裡我只簡單的講幾點:
1、最大的一點是頁面無刷新,在頁面內與伺服器通信,給使用者的體驗非常好。
2、使用非同步方式與伺服器通信,不需要打斷使用者的操作,具有更迅速的回應能力。
3、可以把以前一些伺服器負擔的工作轉嫁到客戶端,利用客戶端閒置的能力來處理,減輕伺服器和頻寬的負擔,節省空間和寬頻租用成本。並且減輕伺服器的負擔,ajax的原則是“按需取資料”,可以最大程度的減少冗餘請求,和回應對伺服器造成的負擔。
4、基於標準化的並被廣泛支援的技術,不需要下載外掛程式或小程式。
7、ajax的缺點
下面我著重講一講ajax的缺陷,因為平常我們大多注意的都是ajax給我們所帶來的好處諸如使用者體驗的提升。而對ajax所帶來的缺陷則有所忽視。
下面所闡述的ajax的缺陷都是它先天產生的。
1、ajax幹掉了back按鈕,也就是對瀏覽器後退機制的破壞。後退按鈕是一個標準的web站點的重要功能,但是它沒辦法和js進行很好的合作。這是ajax所帶來的一個比較嚴重的問題,因為使用者往往是希望能夠透過後退來取消前一次的操作。那麼對於這個問題有沒有辦法呢?答案是肯定的,用過Gmail的知道,Gmail下面採用的ajax技術解決了這個問題,在Gmail下面是可以後退的,但是,它也並不能改變ajax的機制,它只是採用的一個比較笨但是有效的辦法,即使用者點擊後退按鈕存取歷史記錄時,透過建立或使用一個隱藏的IFRAME來重現頁面上的變更。 (例如,當用戶在Google Maps中單擊後退時,它在一個隱藏的IFRAME中進行搜索,然後將搜索結果反映到Ajax元素上,以便將應用程式狀態恢復到當時的狀態。)
但是,雖然說這個問題是可以解決的,但是它所帶來的開發成本是非常高的,和ajax框架所要求的快速開發是相背離的。這是ajax所帶來的一個非常嚴重的問題。
2、安全問題
技術同時也對IT企業帶來了新的安全威脅,ajax技術就如同對企業資料建立了一個直接通道。這使得開發者在不經意間會暴露比以前更多的資料和伺服器邏輯。 ajax的邏輯可以對客戶端的安全掃描技術隱藏起來,讓駭客可以從遠端伺服器建立新的攻擊。還有ajax也難以避免一些已知的安全弱點,諸如跨站點腳步攻擊、SQL注入攻擊和基於credentials的安全漏洞等。
3、對搜尋引擎的支援比較弱。
4、破壞了程式的異常機制。至少從目前看來,像是ajax.dll,ajaxpro.dll這些ajax框架是會破壞程式的異常機制的。關於這個問題,我曾經在開發過程中遇到過,但是查了一下網路上幾乎沒有相關的介紹。後來我自己做了一次試驗,分別採用ajax和傳統的form提交的模式來刪除一條數據……給我們的調試帶來了很大的困難。
5、另外,像是其他方面的一些問題,比如說違背了url和資源定位的初衷。例如,我給你一個url地址,如果採用了ajax技術,也許你在該url地址下面看到的和我在這個url地址下看到的內容是不同的。這個和資源定位的初衷是相背離的。
6、一些手持设备(如手机、PDA等)现在还不能很好的支持ajax,比如说我们在手机的浏览器上打开采用ajax技术的网站时,它目前是不支持的,当然,这个问题和我们没太多关系。
8、ajax的几种框架
目前我们采用的比较多的ajax框架主要有ajax.dll,ajaxpro.dll,magicajax.dll 以及微软的atlas框架。Ajax.dll和Ajaxpro.dll这两个框架差别不大,而magicajax.dll只是封装得更厉害一些,比如说它可以直接返回DataSet数据集,前面我们已经说过,ajax返回的都是字符串,magicajax只是对它进行了封装而已。但是它的这个特点可以给我们带来很大的方便,比如说我们的页面有一个列表,而列表的数据是不断变化的,那么我们可以采用magicajax来处理,操作很简单,添加magicajax之后,将要更新的列表控件放在magicajax的控件之内,然后在pageload里面定义更新间隔的时间就ok了,atlas的原理和magicajax差不多。但是,需要注意的一个问题是,这几种框架都只支持IE,没有进行浏览器兼容方面的处理,用反编译工具察看他们的代码就可以知道。
除了这几种框架之外,我们平时用到的比较多的方式是自己创建xmlHttpRequest对象,这种方式和前面的几种框架相比更具有灵活性。另外,在这里还提一下aspnet2.0自带的异步回调接口,它和ajax一样也可以实现局部的无刷新,但它的实现实际上也是基于xmlhttprequest对象的,另外也是只支持IE,当然这是微软的一个竞争策略。
9.ajax应用举例
以上内容是转载高人写的资料,下面我将我在项目中实际应用给出个例子,这个例子是这样的:我参与的一个项目的值班安排模块里,选择值班人时,弹出的是个联系人树型TreeView结构图,点开哪个部门,然后部门下的联系人就展开了,原先是这样的,选择好某些联系人后,哪天白天或晚上的值班人就是这样的格式”小A,小B”,但是现在要求这样的格式”小A(部门一),小B(部门二)”这里假设小A属于部门一,小B属于部门二。由于选择联系人是纯前台javascript的操作的,这里要通过联系人userlist表中的部门id,来取得部门的名称,也就是通过前台取后台的数据,这个在系列五里我也阐述过,下面给出代码:
var param= "date=<%=stryear%>/<%=strmonth%>/" + x <%=stryear%><%=strmonth%> +"&Type=" + type +"&Other=" + eval_r("formData.RBOTHER"+x+".value") +"&ZBRY=" + eval_r("formData.RBZBRY"+x+".value") +"&ZBRYID=" + eval_r("formData.RBZBRYID"+x+".value") +"&Demo=" + eval_r("formData.RBDEMO"+x+".value") +"&id=" + eval_r("formData.RBZBID"+x+".value");//传递的参数 var retVal = window.showModalDialog( "chooseUsers.asp?"+param,this, "dialogWidth=280px; dialogHeight=500px; help=no; status=no; scroll=no; resizable=yes; "); //弹出对话框取得联系人 //ajax调用服务器端方法取到部门名称 if(retVal ['userIds']!=""&& retVal ['userIds']!=null)//联系人id集合格式1,2,3,4 { var PostUrl=" ../../../Application/CallBoard/GetDepartMentByUid.aspx?userIDs="+objRetVal['userIds']+"";//后台处理页面url xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");//新建一个xmlhttprequest对象 xmlHttp.open("POST", PostUrl, false); xmlHttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded"); xmlHttp.send(""); var builder= xmlHttp.responseText; //将值传递回来,拼成了新格式 eval_r("formData.RBZBRY"+x+".value = '" +builder+"'");// formData.RBZBRY为一文本控件,将显示值班人员新格式 } }
相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!
推荐阅读:
以上是詳解Ajax的原理及優缺點有哪些的詳細內容。更多資訊請關注PHP中文網其他相關文章!