2015-05-17 129 views
4

我正在尋找一個客戶端唯一的JavaScript解決方案,它可以從HTTP服務器以流式傳輸方式接收大型二進制文件,可以在收到數據包後立即做出響應,而無需將所有數據都加載到內存中,並且在處理每個數據後我甚至可以丟棄數據,從而減少內存佔用量。以HTTP格式從HTTP服務器接收二進制數據

我在網上搜索,發現它通過XMLHttpRequest似乎不可能,因爲兩方面的原因(從this article報價),

  • XHR阻止訪問二元響應(與arraybuffer響應類型)數據的請求之前,做完了。
  • XHR響應本質上是一個大的緩衝區,它隨着響應數據的到來而線性增長,這意味着它不能進行垃圾收集。

我不知道這是否可以通過websocket實現,有沒有什麼好的開源已經解決了這個問題?我發現了一些看起來相關的東西,比如Oboe.jsBinary.js,但它可以應付JSON流或需要服務器端支持。

+0

你有沒有遇到過這種情況?目前我正在處理類似的問題。 –

+0

@NickJennings看到我的答案在下面,雖然它不是一個完整的解決方案,它可以滿足我的一些需求。 –

回答

2

使用XMLHttpRequest不能滿足我所有的請求。但是,通過一些技巧,我可以在它到達後讀取塊二進制數據。一般來說,重寫minetype爲'text/plain; charset = x-user-defined',它將二進制數據以文本的形式進行流式處理,一旦一個包準備就緒,我就可以得到它並將其轉換爲arrayBuffer。

var xhr = new XMLHttpRequest(); 
var streamOffset = 0; 

xhr.overrideMimeType('text/plain; charset=x-user-defined'); 
xhr.open("GET", url, true); 
xhr.send(); 
xhr.onreadystatechange = function() { 
    var textBuffer = xhr.responseText; 
    var arrayBuffer = textToArrayBuffer(textBuffer, streamOffset); 
} 
function textToArrayBuffer(textBuffer, startOffset) { 
    var len = textBuffer.length - startOffset; 
    var arrayBuffer = new ArrayBuffer(len); 
    var ui8a = new Uint8Array(arrayBuffer, 0); 
    for (var i = 0, j = startOffset; i < len; i++, j++) 
     ui8a[i] = (textBuffer.charCodeAt(j) & 0xff); 
    return arrayBuffer; 
} 

雖然這樣我就可以以流方式獲取二進制數據,但是在處理每個塊之後不能丟棄,直到請求完成。無論如何,這給了我一旦到達二進制數據的機會。