I have a webpage that uses XMLHttpRequest to load a binary resource.
In Firefox and Gecko, I can use responseText to get bytes, even if the byte stream includes binary zeros. I may need to force mimetype with overrideMimeType() to make this happen. In IE, however, responseText does not work because it seems to end with the first zero. If you read 100,000 bytes, and byte 7 is binary zero, you can only access 7 bytes. IE XMLHttpRequest provides a responseBody property for accessing bytes. I have seen several posts suggesting that it is not possible to access this property in any meaningful way directly from Javascript. That sounds crazy to me.
xhr.responseBody is available from VBScript, so the obvious workaround is to define a method in VBScript on a web page and then call this method from Javascript. See jsdap for an example. EDIT: DO NOT USE THIS VBScript !!
var IE_HACK = (/msie/i.test(navigator.userAgent) && !/opera/i.test(navigator.userAgent)); // no no no! Don't do this! 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('');
It's true? The best way? copy every byte? For a large binary stream that will not be very efficient.
There is also a possible technology using ADODB.Stream, which is the COM equivalent of MemoryStream. See here for an example. It does not require VBScript, but requires 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 }
But this will not work well - ADODB.Stream is disabled on most computers these days.
In IE8 developer tools - the equivalent of Firebug IE - I can see that responseBody is an array of bytes, and I even see the bytes themselves. The data is right there. I donβt understand why I canβt get to him.
Is it possible for me to read it using responseText?
hints? (except for defining a VBScript method)