2009-05-29 02:52

Ajax(XMLHttpRequest) 同步與非同步(異步)連結

首先針對 Internet Explorer 的連結物件做統一的處理,將 ActiveXObject 包裝成與 Mozilla 中的 XMLHttpRequest 相同的物件,這樣我們就可以排除瀏覽器的問題。
  1. /* 針對不同瀏覽器的前置處理宣告 */ 
  2. if (typeof(XMLHttpRequest)=="undefined" && window.ActiveXObject) { 
  3.    XMLHttpRequest=function(){ 
  4.        var arrSignatures = [ 
  5.            "MSXML2.XMLHTTP.5.0", 
  6.            "MSXML2.XMLHTTP.4.0", 
  7.            "MSXML2.XMLHTTP.3.0", 
  8.            "MSXML2.XMLHTTP", 
  9.            "Microsoft.XMLHTTP"]; 
  10.        for (var i = 0; i < arrSignatures.length; i++) { 
  11.            try{ 
  12.                var oRequest = new ActiveXObject(arrSignatures[i]); 
  13.                return oRequest; 
  14.            }catch(oError){/*ignore*/} 
  15.        } 
  16.        throw new Error("MSXML is not installed on your system."); 
  17.    }; 
  18. } 



我們可以直接用 XMLHttpRequest 去處理 Ajax 連結,這是以[GET]方式建立[非同步]的傳送連接,如果要使用 POST 做連結請參考之前的文章[Ajax 使用 POST 傳送]。
POST 的差別只在於 open,setRequestHeader,send 這三個地方的設定。
  1. /**=( 以[GET]方式建立[非同步]傳送連接 )====================*/ 
  2.  
  3. // 產生要求資料的 URL 及 GET 參數 
  4. var sURL = "check_in.php?user=xxxx&pass=xxxx"; 
  5.  
  6. // 建立 XMLHttpRequest 物件,並且送要求  
  7. var oRequest = new XMLHttpRequest(); 
  8.  
  9. // 設定連結方式及位址,並以非同步方式處理 
  10. oRequest.open("GET", sURL, true); 
  11. /* 
  12. void open( 
  13.  in AUTF8String method, 傳送的方式 
  14.  in AUTF8String url, 要求的位址 
  15.  [optional] in boolean async, 同步方式(預設 true 非同步) 
  16.  [optional] in AString user, 使用者名稱(預設為空字串) 
  17.  [optional] in AString password 使用者密碼(預設為空字串) 
  18. ); 
  19. */ 
  20.  
  21. // 建立接收狀態的事件處理  
  22. oRequest.onreadystatechange = function(){ 
  23. /*  
  24. 當狀態變更時都會呼叫此事件 
  25. 可利用 readyState 取得目前的狀態  
  26. 所有可能的傳送狀態值如下: 
  27. 0 (還沒開始) 
  28. 1 (讀取中) 
  29. 2 (已讀取) 
  30. 3 (資訊交換中) 
  31. 4 (請求完成)  
  32. */ 
  33.    switch(oRequest.readyState){ 
  34.        case 0: // 開始前的程式處理 
  35.            break; 
  36.        case 1: // 讀取中的程式處理 
  37.            break; 
  38.        case 2: // 已讀取的程式處理 
  39.            break; 
  40.        case 3: // 資訊交換中的程式處理 
  41.            break; 
  42.        case 4: // 請求完成的程式處理 
  43.            /* (在此處加入開啟已停用選項的設置) */ 
  44.  
  45.            /*可以從responseText或responseXML取得傳回的資料*/ 
  46.            // 處理傳回為 200 的 HTTP 狀態碼  
  47.            if (oRequest.status == 200) { 
  48.                // 接受資料成功  
  49.  
  50.  
  51.                // 將 responseText 中的文字轉成 JSON 物件 
  52.                json = eval('('+oRequest.responseText+')'); 
  53.  
  54.            // 處理其他錯誤 HTTP 狀態碼  
  55.            }else{ 
  56.                /*接收資料失敗,可以從 statusText 取得錯誤狀態資訊*/ 
  57.                alert(oRequest.statusText); 
  58.            } 
  59.            break; 
  60.    }     
  61.  
  62. } 
  63.  
  64. /* (在此處可以加入一些網頁選項停用的設置,以防止重複送出) */ 
  65.  
  66. // 送出 Ajax 要求  
  67. oRequest.send(null); 
  68. /* 
  69. 以POST傳送時,這裡可以輸入(XML,串流,字串,JSON格式) 
  70. 以GET傳送時,這裡只要輸入 null 或是空的 
  71. */ 
  72.  
  73. // 強制中斷  
  74. //oRequest.abort(); 
  75. /* 此函數方法可用在必要時,強制終止非同步請求 */ 



建立[同步]的 Ajax 傳送連接只要將 onreadystatechange 裡的程序移到 send 後面就可以了,如果非必要,最好還是不要以[同步]方式做連結,再處理死結的時候會多一些必要的處理,除非保證連結是 100% 正常且可行的。
  1. /**=( 以[GET]方式建立[同步]傳送連接 )====================*/ 
  2.  
  3. // 產生要求資料的 URL 及 GET 參數 
  4. var sURL = "check_in.php?user=xxxx&pass=xxxx"; 
  5.  
  6. // 建立 XMLHttpRequest 物件,並且送要求  
  7. var oRequest = new XMLHttpRequest(); 
  8.  
  9. // 設定連結方式及位址,並以同步方式處理 
  10. oRequest.open("GET", sURL, false); 
  11. /* 
  12. void open( 
  13.  in AUTF8String method, 傳送的方式 
  14.  in AUTF8String url, 要求的位址 
  15.  [optional] in boolean async, 同步方式(預設 true 非同步) 
  16.  [optional] in AString user, 使用者名稱(預設為空字串) 
  17.  [optional] in AString password 使用者密碼(預設為空字串) 
  18. ); 
  19. */ 
  20.  
  21. /* 開始前的程式處理... */ 
  22.  
  23. /* 讀取中的程式處理... */ 
  24.  
  25. // 送出 Ajax 要求  
  26. oRequest.send(null); 
  27. /* 
  28. 以POST傳送時,這裡可以輸入(XML,串流,字串,JSON格式) 
  29. 以GET傳送時,這裡只要輸入 null 或是空的 
  30. */ 
  31.  
  32. // 請求完成的程式處理 
  33. /*可以從responseText或responseXML取得傳回的資料*/ 
  34. // 處理傳回為 200 的 HTTP 狀態碼  
  35. if (oRequest.status == 200) { 
  36.    // 接受資料成功  
  37.  
  38.    // 將 responseText 中的文字轉成 JSON 物件 
  39.    json = eval('('+oRequest.responseText+')'); 
  40.  
  41. // 處理其他錯誤 HTTP 狀態碼  
  42. }else{ 
  43.    /*接收資料失敗,可以從 statusText 取得錯誤狀態資訊*/ 
  44.    alert(oRequest.statusText); 
  45. } 



參考來源:
XMLHttpRequest - MDC
XMLHttpRequest的同步请求和Firefox的问题_网银

爪哇豆的秘密:AJAX深度歷險1(Getting Started)
Ajax内部交流文档
MoztwWiki:AJAX 上手篇
維基百科:AJAX
語言技術:Ajax Gossip

3 回應:

lucc 提到...

很實用的筆記,謝謝!

レイ 提到...

請問... 我在IE & Firefox的瀏覽器下都能正常執行,但是若是使用Google Chromium來檢視的話,在

//alert('XMLHttpRequest='+typeof XMLHttpRequest);
//alert('ActiveXObject='+window.ActiveXObject);

if (typeof XMLHttpRequest == "undefined" && window.ActiveXObject) {
function XMLHttpRequest2() {
....
}
}
XMLHttpRequest2()這段就會莫名奇妙地被呼叫來使用...(我故意放2在後面方便辨別~)
儘管我已用alert來確定 typeof XMLHttpRequest 以及 window.ActiveXObject都是不成立的
(typeof XMLHttpRequest=function & window.ActiveXObject=undefined)

是不是Google Chromium對於函式的優先使用順序跟其他瀏覽器不同?? 我快被搞瘋了...使用版本為:6.0.472.63

Jax Hu 提到...

Hi,レイ

我的確發現你所說的問題,現在在上面的範例我已經做了修正,並且也證實是可行的。