隨筆-199  評論-203  文章-11  trackbacks-0
            XMLHttpRequest 對象是AJAX功能的核心,要開發AJAX程序必須從了解XMLHttpRequest 對象開始。

              了解XMLHttpRequest 對象就先從創建XMLHttpRequest 對象開始,在不同的瀏覽器中創建XMLHttpRequest 對象使用不同的方法:

              先看看IE創建XMLHttpRequest 對象的方法(方法1):

          var xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");  
          //使用較新版本的 IE 創建 IE 兼容的對象(Msxml2.XMLHTTP)
          var xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); 
          //使用較老版本的 IE 創建 IE 兼容的對(Microsoft.XMLHTTP)

              而 Mozilla、Opera、Safari 和大部分非IE的瀏覽器都使用下面這種方法(方法2)創建XMLHttpRequest 對象:

          var xmlhttp = new XMLHttpRequest();

              實際上Internet Explorer 使用了一個名為 XMLHttp 的對象,而不是 XMLHttpRequest 對象,而 Mozilla、Opera、Safari 和 大部分非 Microsoft 瀏覽器都使用的是后者(下文統稱 XMLHttpRequest 對象)。IE7開始也開始使用XMLHttpRequest 對象了。

              在創建 XMLHttpRequest 對象的時候如果不同的瀏覽器使用了不正確的方法瀏覽器都將會報錯,并且無法使用該對象。所以我們需要一種可以兼容不同瀏覽器的創建XMLHttpRequest 對象的方法:

              創建兼容多瀏覽器的 XMLHttpRequest 對象方法

          var xmlhttp = false; //創建一個新變量 request 并賦值 false。使用 false 作為判斷條件,它表示還沒有創建 XMLHttpRequest 對象。 
          function CreateXMLHttp(){
          try{
          xmlhttp = new XMLHttpRequest();  //嘗試創建 XMLHttpRequest 對象,除 IE 外的瀏覽器都支持這個方法。
          }
          catch (e){
          try{
          xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");  //使用較新版本的 IE 創建 IE 兼容的對象(Msxml2.XMLHTTP)
          }
          catch (e){
          try{
          xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); //使用較老版本的 IE 創建 IE 兼容的對象(Microsoft.XMLHTTP)。
          }
          catch (failed){
          xmlhttp = false;  //如果失敗則保證 request 的值仍然為 false。
          }
          }
          }
          return xmlhttp;
          }
          判斷是否創建成功就很簡單了

           

          if (!xmlhttp){
          //創建XMLHttpRequest 對象失敗!
          }
          else{
          //創建成功!
          }

              創建好了XMLHttpRequest 對象我們再來看看這個對象的方法、屬性以及最重要的onreadystatechange事件句柄吧。

           

              方法:

              open() 說明:初始化 HTTP 請求參數,例如 URL 和 HTTP 方法,但是并不發送請求。

              abort() 說明:取消當前響應,關閉連接并且結束任何未決的網絡活動。

              getAllResponseHeaders() 說明:把 HTTP 響應頭部作為未解析的字符串返回。

              getResponseHeader() 說明:返回指定的 HTTP 響應頭部的值。

              send() 說明:發送 HTTP 請求,使用傳遞給 open() 方法的參數,以及傳遞給該方法的可選請求體。

              setRequestHeader() 說明:向一個打開但未發送的請求設置或添加一個 HTTP 請求。

              屬性:

              readyState 說明:HTTP 請求的狀態。

              responseText 說明:目前為止為服務器接收到的響應體(不包括頭部),或者如果還沒有接收到數據的話,就是空字符串。

              responseXML 說明:對請求的響應,解析為 XML 并作為 Document 對象返回。

              status 說明:由服務器返回的 HTTP 狀態代碼。

              statusText 說明:這個屬性用名稱而不是數字指定了請求的 HTTP 的狀態代碼。

              onreadystatechange 是每次 readyState 屬性改變的時候調用的事件句柄函數。

              下面從發送請求并處理請求結果的過程來理解一下XMLHttpRequest 對象吧。

              發送請求之前自然就是生成一個XMLHttpRequest 對象,代碼上面有了就不多寫了。

              生成一個XMLHttpRequest 對象

          var xmlhttp = CreateXMLHttp();

              創建好XMLHttpRequest 對象了,那我們要送請求到哪個網站呢,就選擇博客園首頁的RSS吧。那怎么設置我要請求的網站地址呢,使用open()方法。

              open(method, url, async, username, password)

              該方法有5個參數,具體什么意思可以看這里:http://www.w3school.com.cn/xmldom/dom_http.asp
          我們用的就是這個了。

              xmlHttp.open("get","http://www.cnblogs.com",true);

              get參數表示用get方法,第二個自然就是目標地址,博客園首頁,第三個就是表示是否異步了,我們當然使用true了。具體的參數說明還都可以到http://www.w3school.com.cn上面看了。

            好了,目標定好了,怎么發送呢。用send()方法?

              send(body),send()方法只有一個參數,表示DOM對象,這個DOM對象需要說明的內容很多,下次說,今天我們只要寫

              xmlhttp.send();就可以了。好了,發送了,那怎么處理返回的結果呢,這個時候就用到XMLHttpRequest 對象最重要的東西了,那就是onreadystatechange事件句柄。什么意思呢,那就需要說明一下XMLHttpRequest 對象的readyState了,readyState有5種狀態,分別用數字的 0 到 4 來表示。

          狀態 名稱 描述
          0 Uninitialized  初始化狀態。XMLHttpRequest 對象已創建(未調用open()之前)或已被 abort() 方法重置。
          1 Open open() 方法已調用,但是 send() 方法未調用。請求還沒有被發送。
          2 Sent Send() 方法已調用,HTTP 請求已發送到 Web 服務器。未接收到響應。
          3 Receiving 所有響應頭部都已經接收到。響應體開始接收但未完成。
          4 Loaded HTTP 響應已經完全接收。

              但是需要注意的是,onreadystatechange事件句柄不同的瀏覽器能處理的狀態并不一致,IE和FireFox能處理1到4,而Safari能處理2到4的狀態,Opera 能處理3、4兩中狀態。0的狀態基本沒什么用,因為創建了XMLHttpRequest 對象后都會馬上調用open() 方法,這時候狀態就變成1了,當然除非你要判斷對象是否已經被 abort() 取消,可是這樣的情況依然很少。大部分情況下判斷是不是4(已經接受完成)這個狀態就夠了。

              好了,明白了readyState有5種狀態了,那處理返回結果就是看狀態變更到不同的狀態我們做不同的處理就可以了,怎么告訴XMLHttpRequest 對象狀態變化時讓誰來處理這個變化呢。有兩種寫法,一種是用匿名方法,另一種是指定方法,其實只是不同的寫發,作用都一樣,看下代碼:

          xmlhttp.onReadyStateChange = function (){
          //處理狀態變化的代碼
          }
          //或者
          xmlhttp.onReadyStateChange = getResult;
          function getResult(){
          ///處理狀態變化的代碼
          }

              順便說一下,句柄的名稱比較長,可以這樣記憶 on ReadyState Change 表示在讀取狀態改變時請求發送了,也指定處理方法了,怎么獲取返回的內容呢,有responseText和responseXML兩個屬性可供使用,responseXML是返回對象,需要再解析,后面再說,這里先用responseText,看看返回什么。

              alert(xmlhttp.responseText); //看看是不是返回了首頁的HTML代碼啊。是你就成功了。

              整個過程是:創建XMLHttpRequest 對象 -> 指定發送地址及發送方法 -> 發送請求 -> 指定處理方法并處理返回結果。但是需要注意,我們正常的思路理解是這樣的,可是onreadystatechange事件句柄指定處理方法需要在發送之前就指定好,否則無法處理狀態變化事件。

              所以我們應該按照下面的流程來記憶:創建XMLHttpRequest 對象 -> 指定發送地址及發送方法 -> 指定狀態變化處理方法 -> 發送請求,請求發送后狀態變化了就會自動調用指定的處理方法。
          好了,看看完成的代碼吧。

              完成的代碼


          var xmlhttp = false; //創建一個新變量 request 并賦值 false。使用 false 作為判斷條件,它表示還沒有創建 XMLHttpRequest 對象。
          function CreateXMLHttp(){
          try{
          xmlhttp = new XMLHttpRequest();  //嘗試創建 XMLHttpRequest 對象,除 IE 外的瀏覽器都支持這個方法。
          }
          catch (e){
          try{
          xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");  //使用較新版本的 IE 創建 IE 兼容的對象(Msxml2.XMLHTTP)
          }
          catch (e){
          try{
          xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); //使用較老版本的 IE 創建 IE 兼容的對象(Microsoft.XMLHTTP)。
          }
          catch (failed){
          xmlhttp = false;  //如果失敗則保證 request 的值仍然為 false。
          }
          }
          }
          return xmlhttp;
          }
          xmlhttp = CreateXMLHttp();
          xmlhttp.open("get","http://www.cnblogs.com",true);
          xmlhttp.onReadyStateChange = getResult;
          xmlhttp.send();
          function getResult(){
          if(xmlhttp.readyState == 4){
          alert(xmlhttp.responseText);
          }
          }

              看似一切都OK了,可是有沒有想過,如果HTML代碼在網絡傳輸過程中出錯了,或者我們指定的地址失效會怎么樣呢。這個時候就需要用到status屬性,即由服務器返回的 HTTP 狀態代碼。 xmlhttp.status 等于200時表示傳輸過程完整沒有錯誤。具體的HTTP狀態代碼什么意思可以到W3C組織網站上看看,地址http://www.w3.org/Protocols/rfc2616/rfc2616-sec6.html#sec6.1.1 。

              把getResult()方法寫成下面這樣我覺的就真的OK了。

           function getResult(){
          if(xmlhttp.readyState == 4 && xmlhttp.status == 200){
          alert(xmlhttp.responseText);
          }
          }

              好了,一個本來挺簡單的東西,被我寫的這么多,好象很羅嗦。不過我覺的編程對基礎內容的理解很重要,現在很多時候開發AJAX的程序都使用很多JS的庫,不需要直接編寫這么基礎的代碼。如使用著名的jQuery,但是如果我們對基礎的東西有很好的理解,那這些庫報告錯誤,或者出現問題我們可以很好很快的知道錯在哪里,更快的做出改變使程序正常運行。

          posted on 2009-04-16 08:14 Werther 閱讀(785) 評論(2)  編輯  收藏 所屬分類: 13.AJAX

          評論:
          # re: 詳解AJAX核心中的XMLHttpRequest對象 2009-04-30 18:02 | 特立獨行
          說得很詳細 剛開始接觸AJAX
          回去好好看看啊
          多謝了哦   回復  更多評論
            
          # re: 詳解AJAX核心中的XMLHttpRequest對象 2013-01-13 18:20 | W3School官網

          只有注冊用戶登錄后才能發表評論。


          網站導航:
           

          I'm reading...

          Java 60

          Head  First SQL

          寶貝連接


          If you need these books,pls send me emails.
          Email:kunpeng.niu@163.com
          <2009年4月>
          2930311234
          567891011
          12131415161718
          19202122232425
          262728293012
          3456789

          留言簿(10)

          隨筆分類(178)

          隨筆檔案(208)

          文章檔案(1)

          新聞檔案(6)

          相冊

          1.Java Official Website

          2.Java Study Website

          3.Java Technic Website

          4.Java Video Website

          5.Database Website

          6.Bookshop Website

          7.English Website

          8.Friends Link

          9.Other Web

          積分與排名

          • 積分 - 684971
          • 排名 - 67

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 北宁市| 大同县| 育儿| 福安市| 鄂托克前旗| 扬中市| 城口县| 葫芦岛市| 怀化市| 柳江县| 罗甸县| 普洱| 加查县| 宁武县| 土默特右旗| 锡林浩特市| 潜江市| 监利县| 白山市| 太白县| 汤阴县| 介休市| 乐山市| 涡阳县| 隆德县| 胶南市| 文化| 荥阳市| 贵南县| 桦南县| 葵青区| 邛崃市| 阿拉尔市| 依兰县| 安阳县| 岳阳市| 万山特区| 扶风县| 吴旗县| 石屏县| 三穗县|