how do I access XHR responseBody from Javascript?
- by Cheeso
I've got a web page that uses XMLHttpRequest to download a binary resource.
Because it's binary I'm trying to use xhr.responseBody to access the bytes. I've seen a few posts suggesting that it's impossible to access the bytes directly from Javascript. This sounds crazy to me.
Weirdly, xhr.responseBody is accessible from VBScript, so the suggestion is that I must define a method in VBScript in the webpage, and then call that method from Javascript. See jsdap for one example.
var IE_HACK = (/msie/i.test(navigator.userAgent) &&
!/opera/i.test(navigator.userAgent));
if (IE_HACK) document.write('<script type="text/vbscript">\n\
Function BinaryToArray(Binary)\n\
Dim i\n\
ReDim byteArray(LenB(Binary))\n\
For i = 1 To LenB(Binary)\n\
byteArray(i-1) = AscB(MidB(Binary, i, 1))\n\
Next\n\
BinaryToArray = byteArray\n\
End Function\n\
</script>');
var xml = (window.XMLHttpRequest)
? new XMLHttpRequest() // Mozilla/Safari/IE7+
: (window.ActiveXObject)
? new ActiveXObject("MSXML2.XMLHTTP") // IE6
: null; // Commodore 64?
xml.open("GET", url, true);
if (xml.overrideMimeType) {
xml.overrideMimeType('text/plain; charset=x-user-defined');
} else {
xml.setRequestHeader('Accept-Charset', 'x-user-defined');
}
xml.onreadystatechange = function() {
if (xml.readyState == 4) {
if (!binary) {
callback(xml.responseText);
} else if (IE_HACK) {
// call a VBScript method to copy every single byte
callback(BinaryToArray(xml.responseBody).toArray());
} else {
callback(getBuffer(xml.responseText));
}
}
};
xml.send('');
Is this really true? The best way? copying every byte? For a large binary stream that's not gonna be very efficient.
There is also a possible technique using ADODB.Stream, which is a COM equivalent of a MemoryStream. See here for an example. It does not require VBScript but does require a separate COM object.
if (typeof (ActiveXObject) != "undefined" && typeof (httpRequest.responseBody) != "undefined") {
// Convert httpRequest.responseBody byte stream to shift_jis encoded string
var stream = new ActiveXObject("ADODB.Stream");
stream.Type = 1; // adTypeBinary
stream.Open ();
stream.Write (httpRequest.responseBody);
stream.Position = 0;
stream.Type = 1; // adTypeBinary;
stream.Read.... /// ???? what here
}
I don't think that's gonna work - ADODB.Stream is disabled on most machines these days.
In The IE8 developer tools - the IE equivalent of Firebug - I can see the responseBody is an array of bytes and I can even see the bytes themselves. The data is right there. I don't understand why I can't get to it.
Is it possible for me to read it with responseText?
hints? (other than defining a VBScript method)