最近有在做 stream 下載,並且邊下載 stream 邊處理功能、解析二進制的功能。最初參考了 flv.js 的 flv stream 下載處理功能,發現他並沒有使用的 XMLHttpRequest 的 responseType = ‘arraybuffer’ 這個功能,而是使用的fetch api 里面的 body.getReader API。(fetch 支持一邊下載二進制數據一邊處理)
后來查詢了資料發現, XMLHttpRequest 里不支持下載 stream 的同時邊處理的 stream。如果你這么做了,你的 xhr.response 一直為null,直到stream完整下載。
- XHR prevents to access the binary response (with arraybuffer response type) data before the request is complete.
- XHR response is essentially one big buffer that keeps growing linearly as the response data comes in which means it can't get garbage collected.
但是可以用另外一種方法繞過去。比如指定找個類型為 text。xhr 就不會下載完才會返回完整數據,而是可以做到邊下載邊獲取數據,但是需要做編碼轉換
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;
}
上面的方法是在對webkit 內核瀏覽器做的兼容,但是其實在火狐瀏覽器和ie瀏覽器中有對這種場景的實現。
XMLHttpRequestResponseType
如下是常見的值:
"arraybuffer" |
ArrayBuffer |
---|---|
"blob" |
Blob |
"document" |
Document |
"json" |
JavaScript object, parsed from a JSON string returned by the server |
"text" |
DOMString |
自己的說明可以參考我之前寫的文章:前端多媒體(2)—— xhr異步接收處理二進制數據
但是我閱讀了一下 flv.js 對非weikit內核的流下載發現其實還有別的瀏覽器類型的實現。在IE和火狐瀏覽器可以做到邊下載留邊獲取流邊處理,而不用等到下載完以后才能處理流
moz-blob
- Used by Firefox to allow retrieving partial
Blob
data from progress events. This lets your progress event handler start processing data while it's still beingreceived. - 在火狐瀏覽器你設置這個值,你可以在progress 事件里獲取到 blob 數據
- Used by Firefox to allow retrieving partial
moz-chunked-text
- Similar to
"text"
, but is streaming. This means that the value inresponse
is only available during dispatch of the"progress"
event and only contains the data received since the last"progress"
event.Whenresponse
is accessed during a"progress"
event it contains a string with the data. Otherwise it returnsnull
.This mode currently only works in Firefox. - 在火狐瀏覽器你設置這個值,和 text 類型相似,但是可以在 response 里獲取 text stream
- Similar to
moz-chunked-arraybuffer
- Similar to
"arraybuffer"
, but is streaming. This means that the value inresponse
is only available during dispatch of the"progress"
event and only contains the data received since the last"progress"
event.Whenresponse
is accessed during a"progress"
event it contains a string with the data. Otherwise it returnsnull
.This mode currently only works in Firefox. - 在火狐瀏覽器你設置這個值, 和 arraybuffer 類型相似,但是可以在 response 里獲取 arraybuffer stream
- Similar to
ms-stream
- Indicates that the response is part of a streaming download. It is supported only for download requests. This mode is available only in Internet Explorer.
- 在 IE 瀏覽器里,可以實現 stream 下載