У меня есть веб-страница, которая использует XMLHttpRequest для загрузки двоичного ресурса.
В Firefox и Gecko я могу использовать responseText для получения байтов, даже если поток байтов содержит двоичные нули. Возможно, мне придется заставить mimetype с помощью overrideMimeType()
, чтобы это произошло. В IE, однако, responseText не работает, потому что он, кажется, заканчивается в первом нуле. Если вы прочитаете 100 000 байтов, а байт 7 - это двоичный ноль, вы сможете получить доступ только к 7 байтам. IEH XMLHttpRequest предоставляет свойство 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 - IE эквиваленте Firebug - я вижу, что responseBody - это массив байтов, и я даже могу видеть сами байты. Данные прямо там . Я не понимаю, почему я не могу добраться до этого.
Можно ли прочитать его с помощью responseText?
намеков? (кроме определения метода VBScript)