我试图加载一个图像客户端和base64编码服务器返回的字节,以传递它来执行一些处理.IE具有XMLHttpRequest对象的RequestBody属性,但我似乎无法使用它,并且RequestText被截断.在Firefox中,RequestText存在,但似乎已损坏.
这就是我做到的.
这个技术是在另一个SO问题的答案中提供的,但它也与此相关.
我不想base64编码任何东西.我想通过Javascript在浏览器中下载和解析二进制文件,而无需修改服务器以对其进行特殊编码.我发现在Firefox中,通过强制响应的mimetype overrideMimeType()
,我可以使用XMLHttpRequest.responseText
.在IE上,它是不同的,因为:
responseText
在IE上截断第一个零点.对于二进制流,这是一个大问题.
没有XMLHttpRequest.overrideMimeType()
,迫使IE将二进制流视为文本.
虽然有一个XMLHttpRequest.responseBody
(IE only!)专门设计用于二进制数据流,但令人抓狂的是Javascript无法使用该属性.
因此,需要将IE的responseBody
属性转换为看起来像responseText
FireFox 的东西,具有mime类型的强制.使用注入的VBScript可以实现这一点.
要使其成为跨浏览器,您需要在条件中打包特定于浏览器的逻辑.这是我用过的:
// one-time code if(/msie/i.test(navigator.userAgent) && !/opera/i.test(navigator.userAgent)) { var IEBinaryToArray_ByteStr_Script = "\r\n"+ "\r\n"; // inject VBScript document.write(IEBinaryToArray_ByteStr_Script); } // each time you make a request for a binary resource: var req = (function() { if (window.XMLHttpRequest) { return new window.XMLHttpRequest(); } else { try { return new ActiveXObject("MSXML2.XMLHTTP"); } catch(ex) { return null; } } })(); var fileContents = ""; var filesize = -1; var readByteAt = function(i){ return fileContents.charCodeAt(i) & 0xff; }; req.open("GET", url, true); if(/msie/i.test(navigator.userAgent) && !/opera/i.test(navigator.userAgent)) { // IE-specific logic here // 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); } } var rawBytes = IEBinaryToArray_ByteStr(binary); var lastChr = IEBinaryToArray_ByteStr_Last(binary); return rawBytes.replace(/[\s\S]/g, function( match ) { return byteMapping[match]; }) + lastChr; }; req.setRequestHeader("Accept-Charset", "x-user-defined"); req.onreadystatechange = function(event){ if (req.readyState == 4) { if (req.status == 200) { fileContents = convertResponseBodyToText(req.responseBody); fileSize = fileContents.length-1; // invoke a callback here, if you like... } else{ alert("download failed, status " + req.status); } } }; req.send(); } else { // ff/Gecko/Webkit specific stuff here req.onreadystatechange = function(aEvt) { if (req.readyState == 4) { // completed if(req.status == 200){ // status == OK fileContents = binStream.req.responseText; filesize = fileContents.length; // invoke a callback here, if you like... } else { alert("download failed, status " + req.status); } } }; // coerce response type req.overrideMimeType('text/plain; charset=x-user-defined'); req.send(null); }
...然后调用readByte(i)
以获取二进制文件中第i个位置的字节.
祝好运.
感谢Miskun的VBScript转换逻辑.