Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

XHR responseType "ms-stream" failing on IE Mobile/Windows Phone 8.1

I'm trying to stream a large amount of binary data in JavaScript, accessing the data before the download completes. In most mainstream browsers, I can use the charset=x-user-defined trick to manually get the raw byte data during the progress event.

In Internet Explorer, however, this trick doesn't work and I'm left with using the VBArray(responseBody).toArray() method instead, which is painfully slow. However, since I only need to support IE 11 and later, I should be able to make use of IE's MSStream to get the data progressively. The following code works fine on IE 11 desktop, but not on a Lumia Windows Phone 8.1 device running IE 11 mobile:

var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.responseType = 'ms-stream';
xhr.onreadystatechange = function () {
    if (xhr.readyState === 3 && xhr.status === 200) {
        // reader is an MSStreamReader object
        reader.readAsArrayBuffer(xhr.response);
    }
};
xhr.send();

On the Windows Phone device, the readyState never goes past 1 and the status is 0, indicating an unknown error occurred even though no actual error is thrown.

Does anyone have any idea why this isn't working for me, or maybe a solution to the problem?

like image 455
Andy E Avatar asked May 05 '15 09:05

Andy E


1 Answers

Assuming you have tried same origin policy solutions and are fairly certain that the issue is not related to same origin policy....

I think the problem is IE is not getting to readystate 3 because it doesn't get that until the entire response is received.

A workaround for this problem is to send down a two kilobyte “prelude” at the top of the response stream—my test simply sends 2kb of spaces. After that initial block is received, the onprogress event is fired as each subsequent block is received from the network.

Also, have you tried this ...

var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.responseType = 'blob';
xhr.onreadystatechange = function () {
    if (xhr.status === 200) {
        var blob = this.response;
        reader.readAsArrayBuffer(blob);
    }
};
xhr.send();
like image 124
Tech Savant Avatar answered Oct 17 '22 00:10

Tech Savant