Emi*_*rch 24 javascript image xmlhttprequest
我试图加载一个图像客户端和base64编码服务器返回的字节,以传递它来执行一些处理.IE具有XMLHttpRequest对象的RequestBody属性,但我似乎无法使用它,并且RequestText被截断.在Firefox中,RequestText存在,但似乎已损坏.
Che*_*eso 12
这就是我做到的.
这个技术是在另一个SO问题的答案中提供的,但它也与此相关.
我不想base64编码任何东西.我想通过Javascript在浏览器中下载和解析二进制文件,而无需修改服务器以对其进行特殊编码.我发现在Firefox中,通过强制响应的mimetype overrideMimeType(),我可以使用XMLHttpRequest.responseText.在IE上,它是不同的,因为:
responseText在IE上截断第一个零点.对于二进制流,这是一个大问题.
没有XMLHttpRequest.overrideMimeType(),迫使IE将二进制流视为文本.
虽然有一个XMLHttpRequest.responseBody(IE only!)专门设计用于二进制数据流,但令人抓狂的是Javascript无法使用该属性.
因此,需要将IE的responseBody属性转换为看起来像responseTextFireFox 的东西,具有mime类型的强制.使用注入的VBScript可以实现这一点.
要使其成为跨浏览器,您需要在条件中打包特定于浏览器的逻辑.这是我用过的:
// one-time code
if(/msie/i.test(navigator.userAgent) && !/opera/i.test(navigator.userAgent)) {
var IEBinaryToArray_ByteStr_Script =
"<!-- IEBinaryToArray_ByteStr -->\r\n"+
"<script type='text/vbscript'>\r\n"+
"Function IEBinaryToArray_ByteStr(Binary)\r\n"+
" IEBinaryToArray_ByteStr = CStr(Binary)\r\n"+
"End Function\r\n"+
"Function IEBinaryToArray_ByteStr_Last(Binary)\r\n"+
" Dim lastIndex\r\n"+
" lastIndex = LenB(Binary)\r\n"+
" if lastIndex mod 2 Then\r\n"+
" IEBinaryToArray_ByteStr_Last = Chr( AscB( MidB( Binary, lastIndex, 1 ) ) )\r\n"+
" Else\r\n"+
" IEBinaryToArray_ByteStr_Last = "+'""'+"\r\n"+
" End If\r\n"+
"End Function\r\n"+
"</script>\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);
}
Run Code Online (Sandbox Code Playgroud)
...然后调用readByte(i)以获取二进制文件中第i个位置的字节.
祝好运.
感谢Miskun的VBScript转换逻辑.
您可以让服务器返回 base64 文本,而不是在客户端进行编码。
例如,(在 ASP.NET 中)对 /ImageAsBase64.ashx?file=/images/myimage.png 的请求可以编码为读取文件、对其进行 base64 编码,并将其作为响应进行流式传输。
在 PHP 或其他语言中,这实际上是几乎相同的事情。
| 归档时间: |
|
| 查看次数: |
60901 次 |
| 最近记录: |