Ajax工做原理及實例

一、關於ajax的名字  javascript

  ajax 的全稱是Asynchronous JavaScript and XML,其中,Asynchronous 是異步的意思,它有別於傳統web開發中採用的同步的方式。html

二、關於同步和異步 java

  步傳輸是面向字符的傳輸,它的單位是字符;而同步傳輸是面向比特的傳輸,它的單位是楨,它傳輸的時候要求接受方和發送方的時鐘是保持一致的。jquery

具體來講,異步傳輸是將比特分紅小組來進行傳送。通常每一個小組是一個8位字符,在每一個小組的頭部和尾部都有一個開始位和一箇中止位,它在傳送過程當中接收方和發送方的時鐘不要求一致,也就是說,發送方能夠在任什麼時候刻發送這些小組,而接收方並不知道它何時到達。一個最明顯的例子就是計算機鍵盤和主機的通訊,按下一個鍵的同時向主機發送一個8比特位的ASCII代 碼,鍵盤能夠在任什麼時候刻發送代碼,這取決於用戶的輸入速度,內部的硬件必須可以在任什麼時候刻接收一個鍵入的字符。這是一個典型的異步傳輸過程。異步傳輸存在 一個潛在的問題,即接收方並不知道數據會在何時到達。在它檢測到數據並作出響應以前,第一個比特已通過去了。這就像有人出乎意料地從後面走上來跟你說 話,而你沒來得及反應過來,漏掉了最前面的幾個詞。所以,每次異步傳輸的信息都以一個起始位開頭,它通知接收方數據已經到達了,這就給了接收方響應、接收 和緩存數據比特的時間;在傳輸結束時,一箇中止位表示該次傳輸信息的終止。按照慣例,空閒(沒有傳送數據)的線路實際攜帶着一個表明二進制1的信號。步傳輸的開始位使信號變成0,其餘的比特位使信號隨傳輸的數據信息而變化。最後,中止位使信號從新變回1,該信號一直保持到下一個開始位到達。例如在鍵盤上數字「1」,按照8比特位的擴展ASCII編碼,將發送「00110001」,同時須要在8比特位的前面加一個起始位,後面一箇中止位。web

同步傳輸的比特分組要大得多。它不是獨立地發送每一個字符,每一個字符都有本身的開始位和中止位,而是把它們組合起來一塊兒發送。咱們將這些組合稱爲數據幀,或簡稱爲幀。ajax

  數據幀的第一部分包含一組同步字符,它是一個獨特的比特組合,相似於前面提到的起始位,用於通知接收方一個幀已經到達,但它同時還能確保接收方的採樣速度和比特的到達速度保持一致,使收發雙方進入同步。json

  幀的最後一部分是一個幀結束標記。與同步字符同樣,它也是一個獨特的比特串,相似於前面提到的中止位,用於表示在下一幀開始以前沒有別的即將到達的數據了。數組

  同步傳輸一般要比異步傳輸快速得多。接收方沒必要對每一個字符進行開始和中止的操做。一旦檢測到幀同步字符,它就在接下來的數據到達時接收它們。另外,同步傳輸的開銷也比較少。例如,一個典型的幀可能有500字節(即4000比特)的數據,其中可能只包含100比特的開銷。這時,增長的比特位使傳輸的比特總數增長2.5%,這與異步傳輸中25 %的增值要小得多。隨着數據幀中實際數據比特位的增長,開銷比特所佔的百分比將相應地減小。可是,數據比特位越長,緩存數據所須要的緩衝區也越大,這就限制了一個幀的大小。另外,幀越大,它佔據傳輸媒體的連續時間也越長。在極端的狀況下,這將致使其餘用戶等得過久。瀏覽器

 三、ajax所包含的技術緩存

  ajax並不是一種新的技術,而是幾種原有技術的結合體。它由下列技術組合而成。

 1.使用CSS和XHTML來表示。

   2. 使用DOM模型來交互和動態顯示。

   3.使用XMLHttpRequest來和服務器進行異步通訊。

   4.使用javascript來綁定和調用。

在上面幾中技術中,除了XmlHttpRequest對象之外,其它全部的技術都是基於web標準而且已經獲得了普遍使用的,XMLHttpRequest雖然目前尚未被W3C所採納,可是它已是一個事實的標準,由於目前幾乎全部的主流瀏覽器都支持它。

   四、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 Ustbwuyi() {

var data = document.getElementById("username").value;
CreateXmlHttp();
if (!xmlhttp) {
alert("建立xmlhttp對象異常!");
return false;
}

xmlhttp.open("POST", url, false);

xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState == 4) {
document.getElementById("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等其它數據類型,只是將這個過程封裝了的結果,本質上他們並無什麼太大的區別。

  五、ajax的缺點

下面我着重講一講ajax的缺陷,由於平時咱們大多注意的都是ajax給咱們所帶來的好處諸如用戶體驗的提高。而對ajax所帶來的缺陷有所忽視。

  下面所闡述的ajax的缺陷都是它先天所產生的。

    一、ajax幹掉了back按鈕,即對瀏覽器後退機制的破壞。後退按鈕是一個標準的web站點的重要功能,可是它無法和js進行很好的合做。這是ajax所帶來的一個比較嚴重的問題,由於用戶每每是但願可以經過後退來取消前一次操做的。那麼對於這個問題有沒有辦法?答案是確定的,用過Gmail的知道,Gmail下面採用的ajax技術解決了這個問題,在Gmail下面是能夠後退的,可是,它也並不能改變ajax的機制,它只是採用的一個比較笨可是有效的辦法,即用戶單擊後退按鈕訪問歷史記錄時,經過建立或使用一個隱藏的IFRAME來重現頁面上的變動。(例如,當用戶在Google Maps中單擊後退時,它在一個隱藏的IFRAME中進行搜索,而後將搜索結果反映到Ajax元素上,以便將應用程序狀態恢復到當時的狀態。)

可是,雖說這個問題是能夠解決的,可是它所帶來的開發成本是很是高的,和ajax框架所要求的快速開發是相背離的。這是ajax所帶來的一個很是嚴重的問題。

     二、安全問題

技術同時也對IT企業帶來了新的安全威脅,ajax技術就如同對企業數據創建了一個直接通道。這使得開發者在不經意間會暴露比之前更多的數據和服務器邏輯。ajax的邏輯能夠對客戶端的安全掃描技術隱藏起來,容許黑客從遠端服務器上創建新的攻擊。還有ajax也難以免一些已知的安全弱點,諸如跨站點腳步攻擊、SQL注入攻擊和基於credentials的安全漏洞等。

     三、對搜索引擎的支持比較弱。

     四、破壞了程序的異常機制。至少從目前看來,像ajax.dll,ajaxpro.dll這些ajax框架是會破壞程序的異常機制的。關於這個問題,我曾經在開發過程當中遇到過,可是查了一下網上幾乎沒有相關的介紹。後來我本身作了一次試驗,分別採用ajax和傳統的form提交的模式來刪除一條數據……給咱們的調試帶來了很大的困難。

     五、另外,像其餘方面的一些問題,好比說違背了url和資源定位的初衷。例如,我給你一個url地址,若是採用了ajax技術,也許你在該url地址下面看到的和我在這個url地址下看到的內容是不一樣的。這個和資源定位的初衷是相背離的。

     六、一些手持設備(如手機、PDA等)如今還不能很好的支持ajax,好比說咱們在手機的瀏覽器上打開採用ajax技術的網站時,它目前是不支持的,固然,這個問題和咱們沒太多關係。

  五、$.ajax()方法詳解   

jquery中的ajax方法參數老是記不住,這裏記錄一下。

1.url
要求爲String類型的參數,(默認爲當前頁地址)發送請求的地址。

2.type
要求爲String類型的參數,請求方式(post或get)默認爲get。注意其餘http請求方法,例如put和delete也可使用,但僅部分瀏覽器支持。

3.timeout
要求爲Number類型的參數,設置請求超時時間(毫秒)。此設置將覆蓋$.ajaxSetup()方法的全局設置。

4.async
要求爲Boolean類型的參數,默認設置爲true,全部請求均爲異步請求。若是須要發送同步請求,請將此選項設置爲false。注意,同步請求將鎖住瀏覽器,用戶其餘操做必須等待請求完成才能夠執行。

5.cache
要求爲Boolean類型的參數,默認爲true(當dataType爲script時,默認爲false),設置爲false將不會從瀏覽器緩存中加載請求信息。

6.data
要求爲Object或String類型的參數,發送到服務器的數據。若是已經不是字符串,將自動轉換爲字符串格式。get請求中將附加在url後。防止這種自動轉換,能夠查看  processData選項。對象必須爲key/value格式,例如{foo1:"bar1",foo2:"bar2"}轉換爲&foo1=bar1&foo2=bar2。若是是數組,JQuery將自動爲不一樣值對應同一個名稱。例如{foo:["bar1","bar2"]}轉換爲&foo=bar1&foo=bar2。

7.dataType
要求爲String類型的參數,預期服務器返回的數據類型。若是不指定,JQuery將自動根據http包mime信息返回responseXML或responseText,並做爲回調函數參數傳遞。可用的類型以下:
xml:返回XML文檔,可用JQuery處理。
html:返回純文本HTML信息;包含的script標籤會在插入DOM時執行。
script:返回純文本JavaScript代碼。不會自動緩存結果。除非設置了cache參數。注意在遠程請求時(不在同一個域下),全部post請求都將轉爲get請求。
json:返回JSON數據。
jsonp:JSONP格式。使用SONP形式調用函數時,例如myurl?callback=?,JQuery將自動替換後一個「?」爲正確的函數名,以執行回調函數。
text:返回純文本字符串。

8.beforeSend
要求爲Function類型的參數,發送請求前能夠修改XMLHttpRequest對象的函數,例如添加自定義HTTP頭。在beforeSend中若是返回false能夠取消本次ajax請求。XMLHttpRequest對象是唯一的參數。
            function(XMLHttpRequest){
               this;   //調用本次ajax請求時傳遞的options參數
            }
9.complete
要求爲Function類型的參數,請求完成後調用的回調函數(請求成功或失敗時均調用)。參數:XMLHttpRequest對象和一個描述成功請求類型的字符串。
          function(XMLHttpRequest, textStatus){
             this;    //調用本次ajax請求時傳遞的options參數
          }

10.success:要求爲Function類型的參數,請求成功後調用的回調函數,有兩個參數。
         (1)由服務器返回,並根據dataType參數進行處理後的數據。
         (2)描述狀態的字符串。
         function(data, textStatus){
            //data多是xmlDoc、jsonObj、html、text等等
            this;  //調用本次ajax請求時傳遞的options參數
         }

11.error:
要求爲Function類型的參數,請求失敗時被調用的函數。該函數有3個參數,即XMLHttpRequest對象、錯誤信息、捕獲的錯誤對象(可選)。ajax事件函數以下:
       function(XMLHttpRequest, textStatus, errorThrown){
          //一般狀況下textStatus和errorThrown只有其中一個包含信息
          this;   //調用本次ajax請求時傳遞的options參數
       }

12.contentType
要求爲String類型的參數,當發送信息至服務器時,內容編碼類型默認爲"application/x-www-form-urlencoded"。該默認值適合大多數應用場合。

13.dataFilter
要求爲Function類型的參數,給Ajax返回的原始數據進行預處理的函數。提供data和type兩個參數。data是Ajax返回的原始數據,type是調用jQuery.ajax時提供的dataType參數。函數返回的值將由jQuery進一步處理。
            function(data, type){
                //返回處理後的數據
                return data;
            }

14.dataFilter
要求爲Function類型的參數,給Ajax返回的原始數據進行預處理的函數。提供data和type兩個參數。data是Ajax返回的原始數據,type是調用jQuery.ajax時提供的dataType參數。函數返回的值將由jQuery進一步處理。
            function(data, type){
                //返回處理後的數據
                return data;
            }

15.global
要求爲Boolean類型的參數,默認爲true。表示是否觸發全局ajax事件。設置爲false將不會觸發全局ajax事件,ajaxStart或ajaxStop可用於控制各類ajax事件。

16.ifModified
要求爲Boolean類型的參數,默認爲false。僅在服務器數據改變時獲取新數據。服務器數據改變判斷的依據是Last-Modified頭信息。默認值是false,即忽略頭信息。

17.jsonp
要求爲String類型的參數,在一個jsonp請求中重寫回調函數的名字。該值用來替代在"callback=?"這種GET或POST請求中URL參數裏的"callback"部分,例如{jsonp:'onJsonPLoad'}會致使將"onJsonPLoad=?"傳給服務器。

18.username
要求爲String類型的參數,用於響應HTTP訪問認證請求的用戶名。

19.password
要求爲String類型的參數,用於響應HTTP訪問認證請求的密碼。

20.processData
要求爲Boolean類型的參數,默認爲true。默認狀況下,發送的數據將被轉換爲對象(從技術角度來說並不是字符串)以配合默認內容類型"application/x-www-form-urlencoded"。若是要發送DOM樹信息或者其餘不但願轉換的信息,請設置爲false。

21.scriptCharset
要求爲String類型的參數,只有當請求時dataType爲"jsonp"或者"script",而且type是GET時纔會用於強制修改字符集(charset)。一般在本地和遠程的內容編碼不一樣時使用。

案例代碼:

複製代碼
$(function(){
    $('#send').click(function(){
         $.ajax({
             type: "GET",
             url: "test.json",
             data: {username:$("#username").val(), content:$("#content").val()},
             dataType: "json",
             success: function(data){
                         $('#resText').empty();   //清空resText裏面的全部內容
                         var html = ''; 
                         $.each(data, function(commentIndex, comment){
                               html += '<div class="comment"><h6>' + comment['username']
                                         + ':</h6><p class="para"' + comment['content']
                                         + '</p></div>';
                         });
                         $('#resText').html(html);
                      }
         });
    });
});
複製代碼
相關文章
相關標籤/搜索