如何使用Javascript和XMLHttpRequest加载二进制图像数据? [英] How do I load binary image data using Javascript and XMLHttpRequest?

查看:203
本文介绍了如何使用Javascript和XMLHttpRequest加载二进制图像数据?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试加载图像客户端,并对服务器返回的字节进行base64编码,以便将其传递出去执行某些处理。 IE具有XMLHttpRequest对象的RequestBody属性,但我似乎无法使用它,并且RequestText被截断。在Firefox中,RequestText存在,但似乎已损坏。

I was trying to load an image client side and base64 encode the bytes returned by the server in order to pass it off to perform some processing. IE has a RequestBody property of the XMLHttpRequest object, but I can't seem to use it, and RequestText is truncated. In Firefox, RequestText is there, but seems corrupted.

推荐答案

以下是我的做法。

这个技术是在另一个SO问题的答案中提供的,但它也与此相关。

This technique is provided in an answer to another SO question, but it's also relevant here.

我不想base64编码任何东西。我想通过Javascript在浏览器中下载和解析二进制文件,而无需修改服务器以对其进行特殊编码。我发现在Firefox中,通过 overrideMimeType()强制响应的mimetype,我可以使用 XMLHttpRequest.responseText 。在IE上,它是不同的,因为:

I didn't want to base64 encode anything. I wanted to download and parse binary files in the browser via Javascript, without modifying the server to encode them specially. I found that in Firefox, by coercing the mimetype of the response via overrideMimeType(), I could use XMLHttpRequest.responseText. On IE, it's different because:


  • responseText 关于IE截断第一个零。对于二进制流,这是一个很大的问题。

  • responseText on IE truncates at the first zero. For binary streams this is a big problem.

没有 XMLHttpRequest.overrideMimeType(),强制IE将二进制流视为文本。

there is no XMLHttpRequest.overrideMimeType(), to force IE to treat binary streams as text.

虽然有 XMLHttpRequest.responseBody (仅限IE) !)专门设计用于二进制数据流,令人抓狂的是Javascript无法使用该属性。

while there is a XMLHttpRequest.responseBody (IE only!) that is specifically designed to be used with binary data streams, maddeningly that property is not usable from Javascript.

因此,需要转换IE的 responseBody 属性使用mime类型的强制,从FireFox看起来像 responseText 的东西。使用注入的VBScript可以实现这一点。

Therefore, the need is to convert IE's responseBody property into a thing that looks like responseText from FireFox, with the mime-type coercion. This is possible using injected VBScript.

要使其成为跨浏览器,您需要在条件中打包特定于浏览器的逻辑。这就是我使用的:

To make it cross-browser, you need to just pack up the browser-specific logic in a conditional. This is what I used:

// 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);
}

...然后拨打 readByte(i)获取二进制文件中 ith 位置的字节。

...then call readByte(i) to get the byte at the ith position in the binary file.

祝你好运。

归功于Miskun 转换逻辑。

这篇关于如何使用Javascript和XMLHttpRequest加载二进制图像数据?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆