当前位置:  开发笔记 > 编程语言 > 正文

如何使用Javascript和XMLHttpRequest加载二进制图像数据?

如何解决《如何使用Javascript和XMLHttpRequest加载二进制图像数据?》经验,为你挑选了1个好方法。

我试图加载一个图像客户端和base64编码服务器返回的字节,以传递它来执行一些处理.IE具有XMLHttpRequest对象的RequestBody属性,但我似乎无法使用它,并且RequestText被截断.在Firefox中,RequestText存在,但似乎已损坏.



1> Cheeso..:

这就是我做到的.

这个技术是在另一个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 =
    "\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转换逻辑.

推荐阅读
小白也坚强_177
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有