大熊君學習html5系列之------XHR2(XMLHttpRequest Level 2)


一,開篇分析

Hi,大家好!大熊君又和大家見面了,(*^__^*) 嘻嘻……,這系列文章主要是學習Html5相關的知識點,以學習API知識點為入口,由淺入深的引入實例,

讓大家一步一步的體會"h5"能夠做什么,以及在實際項目中如何去合理的運用達到使用自如,完美駕馭O(∩_∩)O~,好了,廢話不多說,直接進入今天的主題,

今天主要講的是“XMLHttpRequest Level 2 API”及在客戶端瀏覽器中的作用,並且會引入一個實際的例子做為講解的原型范例,讓我們先來看看“XHR API”:

 

HTML5 世界中有這樣一位無名英雄:"XMLHttpRequest"。嚴格地說,XHR2 並不屬於 HTML5。不過,它是瀏覽器供應商對於核心平台不斷做出的改進中的一部分。

我之所以將" XHR2 "加入到"h5"系列中,就是因為它在如今復雜的網絡應用中扮演了不可或缺的角色,引入了大量的新功能(例如跨源請求、上傳進度事件以及對上傳/下載二進制數據的支持等)。

      

二,溫故而知新

  我們先來一個簡單的回顧:

  (1),XMLHttpRequest Level 1 對象創建

var xhr = new XMLHttpRequest() ;

  (2),建立與Server主機的鏈接並且發出請求

xhr.open('GET', 'bb.jsp') ;
xhr.send() ;

  (3),等待Server主機做出回應,監聽XMLHttpRequest對象的狀態變化,指定回調函數

 

xhr.onreadystatechange = function(){
    if( xhr.readyState == 4 && xhr.status == 200 ) {
     alert( xhr.responseText ) ;
 } 
    else{
     alert( xhr.statusText ) ;
    }
} ;

 

  

 總結一下:相對於新版本"XMLHttpRequest Level 2"來說有一些不足

 只支持文本數據的傳送,無法用來讀取和上傳二進制文件。

 傳送和接收數據時,沒有進度信息,只能提示有沒有完成。

 受到"同域限制"(Same Origin Policy),只能向同一域名的服務器請求數據。

 

 新版本的一些功能擴充:

 可以設置HTTP請求的時限。 

xhr.timeout = 3000 ;
xhr.ontimeout = function(event){
    alert('請求超時!');
} ;

  (最長等待時間設為3000毫秒。過了這個時限,就自動停止HTTP請求。與之配套的還有一個timeout事件,用來指定回調函數。)

  

   可以使用FormData對象管理表單數據。(后面會有詳細的介紹。)

 可以上傳文件。(后面會有詳細的介紹。)

 

 可以請求不同域名下的數據(跨域請求)。

 HTML 5 以前的標准由於考慮到瀏覽器安全問題並不允許直接跨域通信,於是為了達到跨域通信的目的各種蛋疼的解決辦法出現了,

常用的有:jsonp,使用代理文件,地址欄hash等等,這些辦法的出現在達到解決跨域問題的同時,也增加了前端頁面的性能開銷和維護成本。

HTML5新的標准中,增加了” Cross-Origin Resource Sharing”特性,這個特性的出現使得跨域通信只需通過配置http協議頭來即可解決。

  (Cross-Origin Resource Sharing實現的最重要的一點就是對參數” Access-Control-Allow-Origin”的配置,即通過 次參數檢查該跨域請求是否可以被通過。
如:Access-Control-Allow-Origin:http://a.com表示允許a.com下的域名跨域訪問;
Access-Control-Allow-Origin:*表示允許所有的域名跨域訪問。)

  

  如果需要讀取讀取cookie:
  需要配置參數:Access-Control-Allow-Credentials:true
  同時在xhr發起請求的時候設置參數withCredentials為true:
  

    

 

var xhr = new XMLHttpRequest() ;
xhr.open() ;
xhr.withCredentials = true ;  //這個放在xhr.open后面執行,否則有些瀏覽器部分版本會異常,導致設置無效。

  以下為參考實例:

  

 

 可以獲取服務器端的二進制數據。

   老版本的XMLHttpRequest對象,只能從服務器取回文本數據,新版則可以取回二進制數據。分成兩種做法。較老的做法是改寫數據的MIMEType,

將服務器返回的二進制數據偽裝成文本數據,並且告訴瀏覽器這是用戶自定義的字符集。

xhr.overrideMimeType("text/plain; charset=x-user-defined") ;

  新版本處理方式:

var xhr = new XMLHttpRequest() ;
xhr.open('GET', '/path/bb.png') ;
xhr.responseType = 'blob' ;

  

可以獲得數據傳輸的進度信息。

  新版本的XMLHttpRequest對象,傳送數據的時候,有一個progress事件,用來返回進度信息。

 

  它分成上傳和下載兩種情況。下載的progress事件屬於XMLHttpRequest對象,上傳的progress事件屬於XMLHttpRequest.upload對象。

 

  我們先定義progress事件的回調函數。

 

    

xhr.onprogress = updateProgress ;
xhr.upload.onprogress = updateProgress ;

function updateProgress(event) {
    if (event.lengthComputable) {
      var percentComplete = event.loaded / event.total ;
  }
} ;

 

  與progress事件相關的,還有其他五個事件,可以分別指定回調函數:

  

    * load事件:傳輸成功完成。
  * abort事件:傳輸被用戶取消。
  * error事件:傳輸中出現錯誤。
  * loadstart事件:傳輸開始。
  * loadEnd事件:傳輸結束,但是不知道成功還是失敗。

  

三,實例引入

  

<!DOCTYPE HTML>
<html>
    <head>
        <meta charset="utf-8">
        <title>File Upload</title>
        <script src="jquery.min.js"></script>
    </head>
    <body>
        <form id="form">
            <input type="file" name="file" id="file" />
            <input type="text" name="name" id="" value="大熊君{{bb}}}}" />
            <input type="text" name="blog" id="" value="http://www.cnblogs.com/bigbearbb/" />
            <input type="submit" name="do" id="do" value="submit" />
        </form>
        <script>
        $("form").submit(function(e){
            e.preventDefault();
            
            //空對象然后添加
            var fd = new FormData();
            fd.append("name", "大熊君{{bb}}");
            fd.append("blog", "http://www.cnblogs.com/bigbearbb/");
            fd.append("file", document.getElementById("file"));
            //fd.append("file", $(":file")[0].files[0]); //jQuery 方式
            fd.append("do", "submit");
            
            //通過表單對象創建 FormData
            var fd = new FormData(document.getElementById("form"));
            //var fd = new FormData($("form:eq(0)")[0]); //jquery 方式
            
            //XMLHttpRequest 原生方式發送請求
            var xhr = new XMLHttpRequest();       
            xhr.open("POST" ,"" , true);
            xhr.send(fd);
            xhr.onload = function(e) {
                if (this.status == 200) {
                   alert(this.responseText);
                };
            };
            return;
            //jQuery 方式發送請求
            $.ajax({
                type:"post",
                //url:"",
                data: fd,
                processData: false,
                contentType: false
            }).done(function(res){
                console.log(res);
            });  
            return false;
        });
        </script>
    </body>
</html>

  

  

  效果如下:

  

  

 

 

  知識補充:”FormData“ 對象

 

    初始化一個FormData對象

var oMyForm = new FormData();
oMyForm.append("username", "bigbear");
oMyForm.append("accountnum", 123456); // 數字123456被立即轉換成字符串"123456"
// fileInputElement中已經包含了用戶所選擇的文件
oMyForm.append("userfile", fileInputElement.files[0]);
var oFileBody = "<a id="a"><b id="b">hey!</b></a>"; // Blob對象包含的文件內容
var oBlob = new Blob([oFileBody], { type: "text/xml"});
oMyForm.append("webmasterfile", oBlob);

   使用HTML表單來初始化一個FormData對象

 

var formElement = document.getElementById("myFormElement");
var oReq = new XMLHttpRequest();
oReq.open("POST", "submitform.php");
oReq.send(new FormData(formElement));

你還可以在已有表單數據的基礎上,繼續添加新的鍵值對,如下:

var formElement = document.getElementById("myFormElement");
formData = new FormData(formElement);
formData.append("nick","bb");
oReq.send(formData);

 

 

  

(四),最后總結

  (1),理解XMLHttpRequest Level 2 Api的使用方式以及具體實例中使用的目的是為了解決哪些問題。

  (2),XMLHttpRequest Level 2 與 之前老版本的不同之處在哪。

  (3),熟練使用FormData對象,不斷實踐與重構文章中的栗子。

 

 

                   哈哈哈,本篇結束,未完待續,希望和大家多多交流夠溝通,共同進步。。。。。。呼呼呼……(*^__^*)    

 


免責聲明!

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



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