У меня есть веб-страница, использующая XMLHttpRequest. скачать бинарный ресурс.
В Firefox и Gecko я могу использовать responseText для получения байтов, даже если поток байтов включает двоичные нули. Чтобы это произошло, мне может понадобиться принудительно указать тип mimetype с помощью overrideMimeType()
. В IE, тем не менее, responseText не работает, потому что кажется, что он заканчивается на первом нуле. Если вы прочитаете 100 000 байт, а байт 7 будет двоичным нулем, вы сможете получить доступ только к 7 байтам. XMLHttpRequest IE предоставляет свойство responseBody
для доступа к байтам. Я видел несколько сообщений, предполагающих, что невозможно получить доступ к этому свойству каким-либо осмысленным образом непосредственно из Javascript. Это звучит безумно для меня.
xhr.responseBody
доступен из VBScript, поэтому очевидным обходным решением является определение метода в VBScript на веб-странице, а затем вызов этого метода из Javascript. См. один пример в jsdap. РЕДАКТИРОВАТЬ: НЕ ИСПОЛЬЗУЙТЕ ЭТОТ 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('');
Это правда? Лучший путь? копировать каждый байт? Для большого двоичного потока это будет не очень эффективно.
Существует также возможный метод с использованием ADODB.Stream, который является COM-эквивалентом MemoryStream. см. здесь пример. Он не требует VBScript, но требует отдельного COM-объекта.
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
}
Но это не сработает - в наши дни ADODB.Stream отключен на большинстве машин.
В инструментах разработчика IE8 — эквиваленте Firebug для IE — я вижу, что responseBody — это массив байтов, и я даже вижу сами байты. Данные здесь. Я не понимаю, почему я не могу добраться до него.
Могу ли я прочитать его с помощью responseText?
намеки? (кроме определения метода VBScript)