国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

詳解XMLHttpRequest(二)響應屬性、二進制數據、監測上傳下載進度

2019-11-20 09:00:18
字體:
來源:轉載
供稿:網友

分析并操作 responseXML屬性 

如果你使用 XMLHttpRequest 來獲得一個遠程的 XML 文檔的內容,responseXML 屬性將會是一個由 XML 文檔解析而來的 DOM 對象,這很難被操作和分析。這里有五種主要的分析 XML 文檔的方式:
 1.使用 XPath 定位到文檔的制定部分。
 2.使用 JXON 將其轉換成 JavaScript 對象樹。
 3.手工的 解析和序列化 XML 為字符串或對象。
 4.使用 XMLSerializer 把 DOM 樹序列化成字符串或文件。
 5.如果你預先知道 XML 文檔的內容,你可以使用 RegExp。如果你用 RegExp 掃描時受到換行符的影響,你也許想要刪除所有的換行符。然而,這種方法是"最后手段",因為如果 XML 代碼發生輕微變化,該方法將可能失敗。 

解析和操作包含 HTML 文檔的 responseText 屬性 

注意: 在 W3C XMLHttpRequest 規范中允許 HTML 通過 XMLHttpRequest.responseXML 屬性進行解析。更多詳細內容請閱讀 HTML in XMLHttpRequest 。
 如果使用 XMLHttpRequest 從遠端獲取一個 HTML 頁面,則所有 HTML 標記會以字符串的形式存放在responseText 屬性里,這樣就使得操作和解析這些標記變得困難。解析這些HTML標記主要有三種方式:
 1.使用 XMLHttpRequest.responseXML 屬性。
 2.將內容通過 fragment.body.innerHTML 注入到一個 文檔片段 中,并遍歷 DOM 中的片段。
 3.如果你預先知道 HTML 文檔的內容,你可以使用 RegExp 。如果你用 RegExp 掃描時受到換行符的影響,你也許想要刪除所有的換行符。 然而,這種方法是"最后手段",因為如果 HTML 代碼發生輕微變化,該方法將可能失敗。 

Handling binary data 

盡管 XMLHttpRequest 一般用來發送和接收文本數據,但其實也可以發送和接受二進制內容。有許多經過良好測試的方法來強制使用 XMLHttpRequest 發送二進制數據。利用 XMLHttpRequest 的 .overrideMimeType() 方法是一個解決方案,雖然它并不是一個標準方法。

 var oReq = new XMLHttpRequest();oReq.open("GET", url, true);// retrieve data unprocessed as a binary stringoReq.overrideMimeType("text/plain; charset=x-user-defined");/* ... */ 

在 XMLHttpRequest Level 2 規范中新加入了 responseType 屬性 ,使得發送和接收二進制數據變得更加容易。

 var oReq = new XMLHttpRequest();oReq.onload = function(e) { var arraybuffer = xhr.response; // not responseText /* ... */}oReq.open("GET", url, true);oReq.responseType = "arraybuffer";oReq.send(); 

使用JavaScript類型數組接受二進制數據 

可以通過設置一個XMLHttpRequest對象的responseType屬性來改變一個從服務器上返回的響應的數據類型.可用的屬性值為空字符串 (默認), "arraybuffer", "blob", "document", 和 "text". response屬性的值會根據responseType屬性的值的不同而不同, 可能會是一個 ArrayBuffer, Blob, Document, string,或者為NULL(如果請求未完成或失敗)
 下例讀取了一個二進制圖像文件,并且由該文件的二進制原生字節創建了一個8位無符號整數的數組.

 var oReq = new XMLHttpRequest();oReq.open("GET", "/myfile.png", true);oReq.responseType = "arraybuffer";oReq.onload = function (oEvent) { var arrayBuffer = oReq.response; // 注意:不是oReq.responseText if (arrayBuffer) {  var byteArray = new Uint8Array(arrayBuffer);  for (var i = 0; i < byteArray.byteLength; i++) {   // 對數組中的每個字節進行操作  } }};oReq.send(null); 

除了上面的方法,還可以使用 BlobBuilder API 直接將arraybuffer數據添加進一個Blob對象中, 由于該API還在試驗階段,所以需要加上特定的前綴:

 var BlobBuilder = window.MozBlobBuilder || window.WebKitBlobBuilder || window.MSBlobBuilder || window.BlobBuilder;var oReq = new XMLHttpRequest();oReq.open("GET", "/myfile.png", true);oReq.responseType = "arraybuffer";oReq.onload = function(oEvent) { var blobBuilder = new BlobBuilder(); blobBuilder.append(oReq.response); var blob = blobBuilder.getBlob("image/png"); // ...};oReq.send(); 

在老的瀏覽器中接受二進制數據
 下面的load_binary_resource()方法可以從指定的URL那里加載二進制數據,并將數據返回給調用者.

 function load_binary_resource(url) { var req = new XMLHttpRequest(); req.open(/'GET/', url, false); //XHR binary charset opt by Marcus Granado 2006 [http://mgran.blogspot.com] req.overrideMimeType(/'text/plain; charset=x-user-defined/'); req.send(null); if (req.status != 200) return /'/'; return req.responseText;} 

最為奇妙的操作在第五行,該行重寫了默認的MIME類型,強制瀏覽器將該響應當成純文本文件來對待, 使用一個用戶自定義的字符集.這樣就是告訴了瀏覽器,不要去解析數據,直接返回未處理過的字節碼.

 var filestream = load_binary_resource(url);var abyte = filestream.charCodeAt(x) & 0xff; // 扔掉的高位字節(f7) 

上例從請求回來的二進制數據中得到偏移量為x處的字節.有效的偏移量范圍是0到filestream.length-1.
 查看 使用XMLHttpRequest下載文件 了解詳情,查看下載文件.

 發送二進制數據

 XMLHttpRequest對象的send方法已被增強,可以通過簡單的傳入一個ArrayBuffer, Blob, 或者 File對象來發送二進制數據.
 下例創建了一個文本文件,并使用POST方法將該文件發送到了服務器上.你也可以使用文本文件之外的其他二進制數據類型.

 var oReq = new XMLHttpRequest();oReq.open("POST", url, true);oReq.onload = function (oEvent) { // 上傳完成后.};var bb = new BlobBuilder(); // 需要合適的前綴: window.MozBlobBuilder 或者 window.WebKitBlobBuilderbb.append(/'abc123/');oReq.send(bb.getBlob(/'text/plain/')); 

將類型數組作為二進制數據發送
 你可以將JavaScript類型數組作為二進制數據發送出去.

 var myArray = new ArrayBuffer(512);var longInt8View = new Uint8Array(myArray);for (var i=0; i< longInt8View.length; i++) { longInt8View[i] = i % 255;}var xhr = new XMLHttpRequest;xhr.open("POST", url, false);xhr.send(myArray); 

上例新建了一個512字節的8位整數數組并發送它,當然,你也可以發送任意的二進制數據

 監測進度
 支持 DOM 的 progress 事件監測之于 XMLHttpRequest 傳輸,遵循 Web API 進度事件規范 : 這些事件實現了 ProgressEvent 接口。

 var req = new XMLHttpRequest();//上傳監聽req.addEventListener("progress", updateProgress, false);req.addEventListener("load", transferComplete, false);req.addEventListener("error", transferFailed, false);req.addEventListener("abort", transferCanceled, false);req.open(...);...// progress on transfers from the server to the client (downloads)function updateProgress(evt) { if (evt.lengthComputable) {  var percentComplete = evt.loaded / evt.total;  ... } else {  // Unable to compute progress information since the total size is unknown }} 

注意: 你需要在請求調用 open() 之前添加事件監聽。否則 progress 事件將不會被觸發。
 在上個例子中,progress 事件被指定由 updateProgress() 函數處理,并接收到傳輸的總字節數 total 和已經傳輸的字節數loaded ,total是自“Content-Length”頭傳輸的數據的整體長度(字節)。但是如果 lengthComputable 屬性的值是 false,那么總字節數是未知并且 total 的值為0,若知道長度則lengthComputable屬性為true
 progress 事件同時存在于下載和上傳的傳輸。下載相關事件在 XMLHttpRequest 對象上被觸發,就像上面的例子一樣。上傳相關事件在 XMLHttpRequest.upload 對象上被觸發,像下面這樣:

 var req = new XMLHttpRequest();//下載監聽req.upload.addEventListener("progress", updateProgress);req.upload.addEventListener("load", transferComplete);req.upload.addEventListener("error", transferFailed);req.upload.addEventListener("abort", transferCanceled);req.open(); 

注意:progress 事件在使用 file: 協議的情況下是無效的。
 使用 loadend 事件可以偵測到所有的三種加載結束條件(abort、load、error):
 req.addEventListener("loadend", loadEnd, false);
 需要注意的是,沒有方法可以確切的知道 loadend 事件接收到的信息是來自何種條件引起的操作終止;但是你可以在所有傳輸結束的時候使用這個事件處理。 

XMLHttpRequest對象在請求的不同階段觸發不同類型的事件,所以它不需要檢查readyState屬性。
 當調用send()時,觸發單個loadstart事件。當正在加載服務器的響應時,XMLHttpRequest對象會發生progress事件,通常每隔50毫秒左右,所以可以使用這些事件給用戶反饋請求的進度。
 如果請求快速完成,它可能從不會觸發progress事件。當事件完成,會觸發load事件。
 HTTP請求無法完成有3種情況,對應3種事件。如果請求超時,會觸發timeout事件。如果請求中止,會觸發abort事件。像太多重定向這樣的網絡錯誤會阻止請求完成,但這些情況發生時會觸發error事件。
 對于任何具體請求,瀏覽器將只會觸發load、abort、timeout和error事件中的一個,還有progress事件。

 if(/'onprogress/' in (new XMLHttpRequest())){ //檢測是否支持progress事件  var request = new XMLHttpRequest();  request.onprogress = function (e) {    if(e.lengthComputable){      progress.innerHTML = Math.round(100* e.loaded/ e.total) + /'%/';    }  }}

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 昭觉县| 安新县| 宿州市| 汾阳市| 耒阳市| 玉环县| 甘孜县| 都江堰市| 布拖县| 上犹县| 德化县| 韶关市| 裕民县| 临洮县| 连云港市| 秭归县| 尖扎县| 称多县| 黄石市| 延吉市| 万安县| 垣曲县| 鞍山市| 通海县| 湟源县| 望江县| 博兴县| 东宁县| 炎陵县| 福清市| 边坝县| 西盟| 霍林郭勒市| 枣庄市| 华安县| 司法| 寿光市| 云阳县| 关岭| 漯河市| 隆子县|