是的,我想通过IE中的XHR读取二进制数据的答案是使用VBscript注入。一开始这对我来说很令人讨厌,但是,我将其视为仅仅是一个依赖于浏览器的代码。(常规XHR和responseText在其他浏览器中可以正常工作;您可能必须使用来强制MIME类型。IE
XMLHttpRequest.overrideMimeType()]上不提供此功能)。
这就是我得到的东西
responseText即使在二进制数据中也可以在IE中工作的方式。首先,一次性注入一些VBscript,如下所示:
if(/msie/i.test(navigator.userAgent) && !/opera/i.test(navigator.userAgent)) { var IEBinaryToArray_ByteStr_script = "<!-- IEBinaryToArray_ByteStr -->rn"+ "<script type='text/vbscript' language='VBscript'>rn"+ "Function IEBinaryToArray_ByteStr(Binary)rn"+ " IEBinaryToArray_ByteStr = CStr(Binary)rn"+ "End Functionrn"+ "Function IEBinaryToArray_ByteStr_Last(Binary)rn"+ " Dim lastIndexrn"+ " lastIndex = LenB(Binary)rn"+ " if lastIndex mod 2 Thenrn"+ " IEBinaryToArray_ByteStr_Last = Chr( AscB( MidB( Binary, lastIndex, 1 ) ) )rn"+ " Elsern"+ " IEBinaryToArray_ByteStr_Last = "+'""'+"rn"+ " End Ifrn"+ "End Functionrn"+ "</script>rn"; // inject VBscript document.write(IEBinaryToArray_ByteStr_script);}我正在使用的读取二进制文件的JS类公开了一个有趣的方法
readCharAt(i),该方法读取第i个索引处的字符(实际上是一个字节)。这是我的设置方式:
// see doc on http://msdn.microsoft.com/en-us/library/ms535874(VS.85).aspxfunction getXMLHttpRequest() { if (window.XMLHttpRequest) { return new window.XMLHttpRequest; } else { try { return new ActiveXObject("MSXML2.XMLHTTP"); } catch(ex) { return null; } }}// this fn is invoked if IEfunction IeBinFileReaderImpl(fileURL){ this.req = getXMLHttpRequest(); this.req.open("GET", fileURL, true); this.req.setRequestHeader("Accept-Charset", "x-user-defined"); // my helper to convert from responseBody to a "responseText" like thing var convertResponseBodyToText = function (binary) { var byteMapping = {}; for ( var i = 0; i < 256; i++ ) { for ( var j = 0; j < 256; j++ ) { byteMapping[ String.fromCharCode( i + j * 256 ) ] = String.fromCharCode(i) + String.fromCharCode(j); } } // call into VBscript utility fns var rawBytes = IEBinaryToArray_ByteStr(binary); var lastChr = IEBinaryToArray_ByteStr_Last(binary); return rawBytes.replace(/[sS]/g, function( match ) { return byteMapping[match]; }) + lastChr; }; this.req.onreadystatechange = function(event){ if (that.req.readyState == 4) { that.status = "Status: " + that.req.status; //that.httpStatus = that.req.status; if (that.req.status == 200) { // this doesn't work //fileContents = that.req.responseBody.toArray(); // this doesn't work //fileContents = new VBArray(that.req.responseBody).toArray(); // this works... var fileContents = convertResponseBodyToText(that.req.responseBody); fileSize = fileContents.length-1; if(that.fileSize < 0) throwException(_exception.FileLoadFailed); that.readByteAt = function(i){ return fileContents.charCodeAt(i) & 0xff; }; } if (typeof callback == "function"){ callback(that);} } }; this.req.send();}// this fn is invoked if non IEfunction NormalBinFileReaderImpl(fileURL){ this.req = new XMLHttpRequest(); this.req.open('GET', fileURL, true); this.req.onreadystatechange = function(aEvt) { if (that.req.readyState == 4) { if(that.req.status == 200){ var fileContents = that.req.responseText; fileSize = fileContents.length; that.readByteAt = function(i){ return fileContents.charCodeAt(i) & 0xff; } if (typeof callback == "function"){ callback(that);} } else throwException(_exception.FileLoadFailed); } }; //XHR binary charset opt by Marcus Granado 2006 [http://mgran.blogspot.com] this.req.overrideMimeType('text/plain; charset=x-user-defined'); this.req.send(null);}转换码被提供Miskun。
效果很好。
我使用此方法从Javascript读取和提取zip文件,并且还在使用Javascript读取和显示EPUB文件的类中使用了该方法。性能非常合理。500kb文件大约需要半秒钟。



