javascirpt系列之 - XMLHttpRequest對象


  最近在做一個關於Ajax的項目,項目本身非常簡單,但是接手項目之時,設計了過多的特效,導致為了兼容不得不讓代碼幾何增加。設計項目設計圖之時也過於簡單潦草,不過總算完成任務,但不能就此了之,必須得擠些時間出來回顧和總結,將好的一些經驗和不足之處分別進行記錄,避免同一個地方跌倒兩次。

   進入正題,XMLHttpRequest對象其實是瀏覽器的一個標准接口,主要通過http協議與后台服務器交換數據,可惜地是這個接口一直沒有得到W3C的標准化,直到HTML5的概念出現。不過,2008年2月份,已經提出了XMLHttpRequest Level 2的草案。

  創建XMLHttpRequest

  通過XMLHttpRequest對象發送HTTP請求至少需要以下幾個步驟(當然還可以采取更多的其他步驟):

  1. 創建一個XMLHttpRequest對象,目前沒有跨瀏覽器的創建方法;
  2. 指定新創建的XHR對象打開一個特定的文件,也就是調用open()方法;
  3. 通知對象如何處理響應的數據,也就是注冊onreadystatechange事件處理程序;
  4. 讓對象發送請求,調用send()方法。

  路要一步一步走,先創建一個XMLHttpRequest對象。在這里提供一個能兼容絕大部分現存瀏覽器的方法。

function createXHR(){
      if(typeof XMLHttpRequest != "undefined"){
            return new XMLHttpRequest();
      } else if (typeof ActiveXObject != "undefined") {
           var vers = ["MSXML2.XMLHttp.6.0", "MSXML2.XMLHttp.3.0", "MSXML2.XMLHttp.2.0"];
           for (var i = 0, len = vers.length; i < len; i++) {
                try {
                    var xhr = new ActiveXObject(vers[i]);
                    return xhr;
                } catch (ex) {
                    alert("Function createXHR error: " + ex.message);
            continue; } } }
else { throw new Error("No XHR object available."); } }

  不能兼容的主要是IE,因為在早期的IE版本中,這個對象是一個ActiveX對象。"MSXML2.XMLHttp.6.0", "MSXML2.XMLHttp.3.0", "MSXML2.XMLHttp.2.0",這些都是ActiveX對象名稱,具體用哪個取決於用戶的windows配置,而不是瀏覽器決定。里面使用了try/catch語句,如果創建成功,就返回此對象,若不存在的否則進入下一次循環繼續創建。

  打開請求

  下一步,打開一個新請求,這是為發送請求做准備,真正的發送指令是send()。

  open()方法包含三個參數,第一個參數定義為請求的方式:GET、POST、PUT、HEAD等,前面兩個是最常用的,這些方式不區分大小寫,但是通常都以大寫形式出現,以匹配HTTP協議。GET是把數據作為查詢字符串追加在URL上,傳送給服務端,適用於常規請求,例如:URL完全指定了請求資源,或者請求對服務器沒有副作用以及服務器響應可緩存之時;POST是讓數據隨着HTTP請求的正文發送,也就是寫入body內,通常用於發送HTML表單信息,而且是非冪等的,也就是說相同的URL的重復POST請求從服務器端得到的響應可能不同,同時不應該緩存使用這個方法的請求。  

var xhr = createXHR();
xhr.open(type, url, isAsy);     

  HEAD方式使用比較少見,此請求只返回響應的HTTP頭部,而非響應的主體,可以用來顯示文件的最后的修改日期。另外,使用POST方法時,必須記得設置請求的內容類型,這點經常容易忘記,這次有位組成員也犯了此錯誤,不過調試一下,很容易追蹤到這類的錯誤。(Content-Type: [type]/[subtype]; parameter)type常用的幾種形式Text、Application、Image、Message、Audio、Video等,subtype用於指定type的詳細形式,例如:  

  • text/plain(純文本)
  • text/html(HTML文檔)
  • application/xhtml+xml(XHTML文檔)
  • image/gif(GIF圖像)
  • image/jpeg(JPEG圖像)【PHP中為:image/pjpeg】
  • image/png(PNG圖像)【PHP中為:image/x-png】
  • video/mpeg(MPEG動畫)
  • application/octet-stream(任意的二進制數據)
  • application/pdf(PDF文檔)
  • application/msword(Microsoft Word文件)
  • multipart/alternative(HTML郵件的HTML形式和純文本形式,相同內容使用不同形式表示)
  • application/x-www-form-urlencoded(使用HTTP的POST方法提交的表單)
  • multipart/form-data(同上,但主要用於表單提交時伴隨文件上傳的場合)

  url參數時訪問服務端數據的URI,疊加查詢字符串也需要用到,最后的isAys是通知瀏覽器是否需要異步的布爾值,true為異步,false為同步,缺省值為false。異步也即是說,在進行某些需要比較長時間的操作時,瀏覽器不必等到服務端的數據返回,而是立即執行后面的代碼,接觸過回調函數的TX很容易理解這點。反之,則需要無聊地等待。當然,絕大部分情況下,都是用true,要不然沒必要是用XHR。

  注冊處理事件程序

  接着,需要先注冊readystatechange事件處理程序,必須在open()方法之后,send()方法之前。事件處理程序也就是根據服務端返回的readystate進行判斷,是否可以進行響應的數據處理。readystatechange事件一共五個就緒的狀態,web開發者必須得將它們熟爛在肚子里。

數值 意義 詳細描述
0 未初始化(UNSENT) 已經創建了XHR對象,但未調用open()
1 加載中(OPENED) 已經創建了XHR對象,但未調用send()
2 已加載(HEADERS_RECEIVED) 已調用send(),但是狀態和頭信息還不可以使用
3 交互中(LOADING) 已經接受到了部分數據信息
4 完成(DONE) 所有的數據接受完成,全部可以使用

  就緒狀態4最為常見,意思為可以使用response對象的數據信息。

  發送操作

  緊接着,調用send()方法,send方法需要一個參數,若是POST方法,參數就是傳遞的數據,也就是body內容;若是GET方法,參數就是null。發送請求后,等待響應到達。(此處未考慮多個request異步並發)一旦到達,onreadystatechange事件處理程序就被激發,並按照指示執行事情。

  時間關系,未完待續....(已經11:35)

 參考資料:http://www.w3.org/Protocols/rfc2616/rfc2616.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM